package com.topisv.tms.service;

import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Vector;

import javax.persistence.EntityManager;
import javax.persistence.PersistenceContext;
import javax.persistence.Query;
import javax.persistence.criteria.CriteriaBuilder;
import javax.persistence.criteria.CriteriaQuery;
import javax.persistence.criteria.Predicate;
import javax.persistence.criteria.Root;

import org.apache.commons.lang.StringUtils;
import org.apache.shiro.SecurityUtils;
import org.hibernate.SQLQuery;
import org.hibernate.ejb.criteria.predicate.ComparisonPredicate;
import org.hibernate.transform.Transformers;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.PageRequest;
import org.springframework.data.jpa.domain.Specification;
import org.springframework.jdbc.core.JdbcTemplate;
import org.springframework.stereotype.Component;
import org.springframework.transaction.annotation.Transactional;
import org.springside.modules.persistence.DynamicSpecifications;
import org.springside.modules.persistence.SearchFilter;
import org.springside.modules.persistence.SearchFilter.Operator;

import com.topisv.tms.api.AliLogisticsAPIUtils;
import com.topisv.tms.entity.AreaGroup;
import com.topisv.tms.entity.CusStockMerge;
import com.topisv.tms.entity.CustomerAreaGroup;
import com.topisv.tms.entity.Customers;
import com.topisv.tms.entity.CustomersOrdenoSource;
import com.topisv.tms.entity.EdiGoodsSku;
import com.topisv.tms.entity.EdiOrder;
import com.topisv.tms.entity.EdiOrderItem;
import com.topisv.tms.entity.QueryParamHolder;
import com.topisv.tms.entity.ShopSource;
import com.topisv.tms.entity.SubWarehouseRel;
import com.topisv.tms.entity.User;
import com.topisv.tms.entity.ediOrder.EdiOrderVO;
import com.topisv.tms.entity.log.OrderLog;
import com.topisv.tms.entity.task.DispatchOrderTask;
import com.topisv.tms.entity.task.MdSendOutTask;
import com.topisv.tms.entity.work.WorkOrder;
import com.topisv.tms.entity.work.inscope.InScope;
import com.topisv.tms.entity.work.outScope.OutScope;
import com.topisv.tms.entity.work.outScope.ScopeCustomerConfig;
import com.topisv.tms.repository.AreaGroupDao;
import com.topisv.tms.repository.CusStockMergeDao;
import com.topisv.tms.repository.CustomerAreaGroupDao;
import com.topisv.tms.repository.CustomersDao;
import com.topisv.tms.repository.CustomersOrdenoSourceDao;
import com.topisv.tms.repository.EdiGoodsSkuDao;
import com.topisv.tms.repository.EdiOrderDao;
import com.topisv.tms.repository.EdiOrderItemDao;
import com.topisv.tms.repository.ShopSourceDao;
import com.topisv.tms.repository.SubWarehouseRelDao;
import com.topisv.tms.repository.UserDao;
import com.topisv.tms.repository.log.OrderLogDao;
import com.topisv.tms.repository.stock.ViewCusStockDao;
import com.topisv.tms.repository.task.MdSendOutTaskDao;
import com.topisv.tms.repository.work.WorkOrderDao;
import com.topisv.tms.repository.work.inscope.InScopeDao;
import com.topisv.tms.repository.work.outScope.OutScopeDao;
import com.topisv.tms.service.account.ShiroDbRealm.ShiroUser;
import com.topisv.tms.service.base.BaseService;
import com.topisv.tms.service.deppon.DepponService;
import com.topisv.tms.service.ttkdex.TTKDEXService;
import com.topisv.tms.service.yunda.YUNDAService;
import com.topisv.tms.utils.DateUtils;
import com.topisv.tms.utils.EdiOrderUtil;
import com.topisv.tms.utils.WmsContants;
import com.topisv.tms.utils.enums.MDOrderType;
import com.topisv.tms.utils.enums.StatusEnums;
import com.topisv.tms.utils.enums.TaskStatus;
import com.topisv.tms.utils.rule.CreateOrdeno;
import com.topisv.tms.utils.rule.TMSRule;

//Spring Bean的标识.
@Component
// 默认将类中的所有public函数纳入事务管理.
@Transactional(readOnly = true)
public class EdiOrderService extends BaseService {

	private Logger log = LoggerFactory.getLogger(EdiOrderService.class);
	private Logger logOrderCount = LoggerFactory.getLogger("OrderCount");

	@Autowired
	private EdiOrderDao ediOrderDao;
	@Autowired
	private EdiOrderItemDao ediOrderItemDao;
	@Autowired
	private CustomersDao customersDao;
	@Autowired
	private TMSRule tMSRule;
	@Autowired
	private CustomersOrdenoSourceDao customersOrdenoSourceDao;
	@Autowired
	private ViewCusStockDao viewCusStockDao;
	@Autowired
	private CusStockMergeDao cusStockMergeDao;
	@Autowired
	private CustomerAreaGroupDao customerAreaGroupDao;
	@Autowired
	private AreaGroupDao areaGroupDao;
	@Autowired
	private ShopSourceDao shopSourceDao;
	@Autowired
	private OutScopeDao outScopeDao;
	@Autowired
	private InScopeDao inScopeDao;
	@Autowired
	private MdSendOutTaskDao mdSendOutTaskDao;
	@Autowired
	private OrderLogDao orderLogDao;
	@Autowired
	private SubWarehouseRelDao subWarehouseRelDao;
	@Autowired
	private DepponService depponService;
	@Autowired
	private TTKDEXService ttkdexService;
	@Autowired
	private YUNDAService yundaService;
	@Autowired
	private EdiGoodsSkuDao ediGoodsSkuDao;
	@Autowired
	private UserDao userDao;
	@Autowired
    private JdbcTemplate jdbcTemplate;
	@Autowired
	private WorkOrderDao workOrderDao;
	public EdiOrder getEdiOrder(String customerCode, String ordeno) {
		List<EdiOrder> orderList = ediOrderDao.findByCustomerCodeAndCustomerOrdeno(customerCode, ordeno);
		EdiOrder e = orderList.isEmpty() ? null : orderList.get(0);
		if (e == null) {
			orderList = ediOrderDao.findByCustomerCodeAndFromno(customerCode, ordeno);
			e = orderList.isEmpty() ? null : orderList.get(0);
			if (e == null) {
				e = ediOrderDao.findByOrdeno(ordeno);
				if (e == null) {
				}
			}

		}
		return e;
	}

	/**
	 * 
	 * @param pageNumber
	 * @param pageSize
	 * @param sortType
	 * @param provna
	 * @param ordeno
	 * @param shopna
	 * @param recena
	 * @param fromno
	 * @param customers
	 * @param areagroups
	 * @return
	 */
	public Page<EdiOrder> getPageEdiOrders(int pageNumber, int pageSize, String sortType, String customerOrdeno, String provna, String ordeno, String shopna, String recena, String fromno, String customers) {
		PageRequest pageRequest = buildPageRequest(pageNumber, pageSize, sortType);
		Specification<EdiOrder> spec = buildSpecification(customerOrdeno, provna, ordeno, shopna, recena, fromno, customers);
		return ediOrderDao.findAll(spec, pageRequest);
	}

	private Specification<EdiOrder> buildSpecification(final String customerOrdeno, final String provna, final String ordeno, final String shopna, final String recena, final String fromno, final String customers) {
		return new Specification<EdiOrder>() {
			@Override
			public Predicate toPredicate(Root<EdiOrder> r, CriteriaQuery<?> q, CriteriaBuilder cb) {

				Predicate pre = cb.conjunction();
				if (StringUtils.isNotBlank(customers)) {
					String[] customerLists = customers.split(":");
					ComparisonPredicate[] tempCustomerCode = new ComparisonPredicate[customerLists.length];
					int i = 0;
					for (String customer : customerLists) {
						tempCustomerCode[i] = (ComparisonPredicate) cb.equal(r.get("customerCode"), customer);
						i++;
					}
					pre.getExpressions().add(cb.or(tempCustomerCode));
				}

				if (StringUtils.isNotBlank(customerOrdeno)) {
					pre.getExpressions().add(cb.like(r.<String> get("customerOrdeno"), customerOrdeno));
				}

				if (StringUtils.isNotBlank(provna)) {
					pre.getExpressions().add(cb.like(r.<String> get("provna"), provna));
				}

				if (StringUtils.isNotBlank(ordeno)) {
					pre.getExpressions().add(cb.like(r.<String> get("ordeno"), ordeno));
				}

				if (StringUtils.isNotBlank(shopna)) {
					pre.getExpressions().add(cb.like(r.<String> get("shopna"), shopna));
				}

				if (StringUtils.isNotBlank(recena)) {
					pre.getExpressions().add(cb.like(r.<String> get("recena"), recena));
				}

				if (StringUtils.isNotBlank(fromno)) {
					pre.getExpressions().add(cb.like(r.<String> get("fromno"), fromno));
				}

				return pre;
			}

		};
	}

	public EdiOrder findByCustomerCodeAndFromno(String customerCode, String fromno) {
		List<EdiOrder> fromno2 = ediOrderDao.findByCustomerCodeAndFromno(customerCode, fromno);
		return fromno2.isEmpty() ? null : fromno2.get(0);
	}

	public List<EdiOrder> findByGymemo(String gymemo) {
		return ediOrderDao.findByGymemo(gymemo);
	}

	@Transactional(readOnly = false)
	public void delete(Long id) throws Exception {
		try {
			EdiOrder ediOrder = ediOrderDao.findOne(id);
			ediOrderItemDao.deleteOrdeno(ediOrder.getCustomerCode(), ediOrder.getOrdeno());
			ediOrderDao.delete(id);
		} catch (Exception e) {

			throw e;
		}
	}

	public EdiOrder findByOrdeno(String ordeno) {
		return ediOrderDao.findByOrdeno(ordeno);
	}

	public List<EdiOrder> findByCrtimeBetween(Date fromDate, Date endDate) {
		return ediOrderDao.findByCrtimeBetween(fromDate, endDate);
	}

	@Transactional(readOnly = false)
	public void updateEdiOrder(String orderType, Long id) {
		ediOrderDao.updateEdiOrder(orderType, id);
	}

	@Transactional(readOnly = false)
	public List<EdiOrder> save(List<EdiOrder> ediOrders) throws Exception {
		try {
			return (List<EdiOrder>) ediOrderDao.save(ediOrders);
		} catch (Exception e) {
			throw e;
		}
	}

	@Transactional(readOnly = false)
	public EdiOrder save(EdiOrder ediOrder) throws Exception {
		try {
			/*
			 * modify by cc 2015年1月6日 这段代码会导致作业仓发生变化，先删除
			 * if("ocr".equals(ediOrder.getErpType())){
			 * ediOrder.setWarehouseCode(ediOrder.getAreaGroupCode()); }
			 */
			return ediOrderDao.save(ediOrder);
		} catch (Exception e) {
			throw e;
		}
	}

	/**
	 * 合并订单
	 * @param e
	 * @return
	 */
	@Transactional(rollbackFor = Exception.class, readOnly = false)
	public EdiOrder margeOrdeno(EdiOrder e) throws Exception {
		try {
			String ordeno = null;
			String waybillNo = null;
			Long id = null;
			List<EdiOrder> ediOrders = null;
			List<CustomersOrdenoSource> customersOrdenoSources = customersOrdenoSourceDao.findByCustomerCode(e.getCustomerCode());
			if (customersOrdenoSources == null || customersOrdenoSources.isEmpty()) {
				log.info("没有设置合单条件");
				return e;// 没有设置合单
			}
			for (CustomersOrdenoSource cos : customersOrdenoSources) {
				if (!StringUtils.isBlank(cos.getShopCodes()) && cos.getShopCodes().indexOf(e.getErpType()) > -1) {
					ediOrders = margeOrdeno(e, cos);
					break;
				}
			}

			if (ediOrders == null || ediOrders.isEmpty()) {
				log.info("没有找到合单条件");
				return e;
			}
			log.info("开始合单");
			List<EdiOrderItem> ediOrderItems = e.getSkulst();
			StringBuffer customerOrdeno = new StringBuffer();
			StringBuffer fromnoOrdeno = new StringBuffer();
			int skuQty = 0;
			Customers customers = this.customersDao.findByCustomerCode(e.getCustomerCode());
			for (EdiOrder eo : ediOrders) {
				if (ordeno == null) {
					ordeno = eo.getOrdeno();
				}
				if (waybillNo == null) {
					waybillNo = eo.getWaybillNo();
				}
				if (id == null) {
					id = eo.getId();
				}
				e.setDispatchFlag(eo.getDispatchFlag());
				List<EdiOrderItem> tempediOrderItems = ediOrderItemDao.findByCustomerCodeAndOrdeno(eo.getCustomerCode(), eo.getOrdeno());
				for (EdiOrderItem tempediOrderItem : tempediOrderItems) {
					if ("1".equals(customers.getPlaceStatus()) && !"no".equals(e.getOrderStatus())) {
						CusStockMerge cusStockMerge = this.cusStockMergeDao.findCustomerWarSku(e.getCustomerCode(), e.getWarehouseCode(), tempediOrderItem.getSku());
						cusStockMerge.setOrderNum(cusStockMerge.getOrderNum() - tempediOrderItem.getQty());
						this.cusStockMergeDao.save(cusStockMerge);
					}
					margeOrdeno(ediOrderItems, tempediOrderItem);
				}
				customerOrdeno.append(":" + eo.getCustomerOrdeno());
				fromnoOrdeno.append(":" + eo.getFromno());
				skuQty += eo.getSkuQty();
			}
			for (EdiOrderItem ei : ediOrderItems) {
				ei.setOrdeno(ordeno);
			}
			e.setSkuQty(e.getSkuQty() + skuQty);
			e.setOrderType("multiple");
			e.setId(id);
			e.setWaybillNo(waybillNo);// 能容运单号
			e.setFromno(e.getFromno() + fromnoOrdeno.toString());// 来源单号
			e.setCustomerOrdeno(e.getCustomerOrdeno() + customerOrdeno.toString());// 商家订单号
			e.setOrdeno(ordeno);// 订单号
		} catch (Exception e2) {
			throw e2;
		}
		return e;
	}

	private void margeOrdeno(List<EdiOrderItem> ediOrderItems, EdiOrderItem tempediOrderItem) {
		boolean fa = true;
		for (EdiOrderItem ediOrderItem : ediOrderItems) {
			if (tempediOrderItem.getSku().equals(ediOrderItem.getSku())) {
				ediOrderItem.setId(tempediOrderItem.getId());
				ediOrderItem.setQty(tempediOrderItem.getQty() + ediOrderItem.getQty());
				fa = false;
				break;
			}
		}
		if (fa) {
			ediOrderItems.add(tempediOrderItem);
		}
	}

	/**
	 * 合并订单
	 * @param filterParams
	 * @return
	 */
	private List<EdiOrder> margeOrdeno(final EdiOrder ediOrder, final CustomersOrdenoSource customersOrdenoSource) {
		Specification<EdiOrder> spec = margeOrdenoBuildSpecification(ediOrder, customersOrdenoSource);
		return ediOrderDao.findAll(spec);
	}

	private Specification<EdiOrder> margeOrdenoBuildSpecification(final EdiOrder ediOrder, final CustomersOrdenoSource customersOrdenoSource) {
		return new Specification<EdiOrder>() {
			@Override
			public Predicate toPredicate(Root<EdiOrder> r, CriteriaQuery<?> q, CriteriaBuilder cb) {
				Predicate pre = cb.conjunction();
				String sourceLists = customersOrdenoSource.getShopCodes();// 平台编码
				if (StringUtils.isNotBlank(sourceLists)) {
					String[] sourceList = sourceLists.split(":");
					ComparisonPredicate[] tempCustomerCode = new ComparisonPredicate[sourceList.length];
					int i = 0;
					for (String source : sourceList) {
						tempCustomerCode[i] = (ComparisonPredicate) cb.equal(r.get("erpType"), source);
						i++;
					}
					pre.getExpressions().add(cb.or(tempCustomerCode));
				}

				String paramLists = customersOrdenoSource.getMergeOrdenos();// 订单属性
				if (StringUtils.isNotBlank(paramLists)) {
					String[] paramList = paramLists.split(":");
					for (String param : paramList) {
						String value = null;
						try {
							value = replaceParams(ediOrder, param);
						} catch (Exception e) {
							// TODO Auto-generated catch block

						}
						pre.getExpressions().add(cb.like(r.<String> get(param), value));
					}
				}
//				pre.getExpressions().add(cb.equal(r.<String> get("areaGroupCode"), ediOrder.getAreaGroupCode()));
				pre.getExpressions().add(cb.equal(r.<String> get("warehouseCode"), ediOrder.getWarehouseCode()));
				pre.getExpressions().add(cb.equal(r.<String> get("status"), ediOrder.getStatus()));
				pre.getExpressions().add(cb.equal(r.<String> get("orderStatus"), ediOrder.getOrderStatus()));
				pre.getExpressions().add(cb.equal(r.<String> get("customerCode"), ediOrder.getCustomerCode()));
//				pre.getExpressions().add(cb.equal(r.<String> get("dispatchFlag"), ediOrder.getDispatchFlag()));
				pre.getExpressions().add(cb.greaterThan(r.<Date> get("crtime"), DateUtils.getDateDayAdd(new Date(),-2)));
				return pre;
			}

			private String replaceParams(EdiOrder ediOrder, String paramName) throws Exception {
				Object object = null;
				try {
					Class<EdiOrder> clazz = EdiOrder.class;
					Method method = clazz.getMethod(getMethod(paramName));
					object = method.invoke(ediOrder);
				} catch (Exception e) {
					// TODO: handle exception
				}

				return object.toString();
			}

			private String getMethod(String param) {
				StringBuffer sb = new StringBuffer(param.subSequence(0, 1));
				String result = "get" + sb.toString().toUpperCase() + param.substring(1);
				return result;
			}

		};
	}

	public Page<EdiOrder> getPageEdiOrders(QueryParamHolder paramHolder) {
		return findByJson(paramHolder, ediOrderDao, EdiOrder.class);
	}

	@Transactional(rollbackFor = Exception.class, readOnly = false)
	public EdiOrder saveEdiOrder(EdiOrder ediOrders, boolean merge) throws Exception {
		try {
			// 合并订单
			if (merge) {
				try {
					ediOrders = margeOrdeno(ediOrders);
				} catch (Exception e) {
					log.error("merge case error.", e);
				}
			}
			//add by yanlei   防止重复推单
			/*List<EdiOrder> ediOrder1 = ediOrderDao.findByCustomerCodeAndCustomerOrdenoAndOrderStatus(ediOrders.getCustomerCode(), ediOrders.getCustomerOrdeno());
			if (!ediOrder1.isEmpty()) {
				ediOrders.setStatus("repeat");
				ediOrders.setMessage("订单重复流入");
				log.info("奇门订单重复流入："+ediOrders.getCustomerCode() + "+++" + ediOrders.getCustomerOrdeno());
				return ediOrders;
			}*/
			
			if (null == ediOrders.getOrdeno()) {
				CreateOrdeno.setOrdenrOrdeno(ediOrders, tMSRule);// 能容订单号赋值
			}
			if (ediOrders.getWaybillNo() == null) {
				ediOrders.setWaybillNo(tMSRule.getNumber(ediOrders.getCustomerCode()));
			}
			List<EdiOrderItem> orderItems = ediOrders.getSkulst();
			Date nowDate = new Date();
			int qty = 0;
			for (EdiOrderItem ei : orderItems) {
				ei.setCrtime(nowDate);
				ei.setWaybillNo(ediOrders.getWaybillNo());
				ei.setCustomerCode(ediOrders.getCustomerCode());
				ei.setOrdeno(ediOrders.getOrdeno());
				ediOrderItemDao.save(ei);
				qty += ei.getQty();
			}

			ediOrders.setGymemo("1");
			ediOrders.setSkuQty(qty);
			ediOrders.setOrderType(qty > 1 ? StatusEnums.ORDER_TYPE_MULTIPLE.getStatus() : StatusEnums.ORDER_TYPE_SINGLE.getStatus());
			ediOrderDao.save(ediOrders);
			// SaveEdiOrdenoRedis.saveRedis(redisEdiOrdenoService, ediOrders);
			try {
				OrderLog orderLog = new OrderLog(ediOrders.getOrdeno(), ediOrders.getCustomerCode(), "0", null, new Date(), null, "系统接收订单");
				orderLogDao.save(orderLog);
			} catch (Exception e) {
				log.error("失败:", e);
			}
			return ediOrders;
		} catch (Exception e) {
			throw e;
		}
	}

	@Transactional(rollbackFor = Exception.class, readOnly = false)
	public EdiOrder saveEdiOrder(EdiOrder ediOrders) throws Exception {
		return saveEdiOrder(ediOrders, true);
	}

	/**
	 * 批量保存
	 * @param ediOrders
	 * @param merge 是否合并订单
	 * @return
	 * @throws Exception List<EdiOrder>
	 */
	@Transactional(rollbackFor = Exception.class, readOnly = false)
	public List<EdiOrder> saveEdiOrder(List<EdiOrder> ediOrders, boolean merge) throws Exception {
		for (EdiOrder ediOrder : ediOrders) {
			saveEdiOrder(ediOrder, merge);
		}
		return ediOrders;
	}

	/**
	 * 保存美的推送的订单
	 * @param ediOrders
	 * @throws Exception
	 */
	@Transactional(rollbackFor = Exception.class, readOnly = false)
	public void saveEdiOrder4MD(List<EdiOrder> ediOrders) throws Exception {
		saveEdiOrder(ediOrders, false);
		// 生成处理任务
		MdSendOutTask task = new MdSendOutTask();
		int qty = EdiOrderUtil.countOrderSkuQty(ediOrders);
		task.setCrTime(new Date());
		task.setDealStatus("0");
		task.setCustomerOrderNo(ediOrders.get(0).getCustomerOrdeno());
		task.setWorkNum(qty);
		task.setDoneNum(0);
		task.setDealCount(0);
		task.setOrderType(MDOrderType.SALE.getType());
		// 超过10单 预警
		/*if(10 < qty){
			SMSTool.sendMsgByGet("15800510179,15221958978,13301313367,18658897193,13821763525,18001205559,18566106168,13247139319", new StringBuilder().append("订单号[").append(ediOrders.get(0).getCustomerOrdeno()).append("]商品数量超过10件,请留意处理.").toString());
		}*/
		mdSendOutTaskDao.save(task);
	}
	
	/**
	 * 保存美的推送的订单
	 * @param ediOrders
	 * @throws Exception
	 */
	@Transactional(rollbackFor=Exception.class,readOnly = false)
	public void  saveEdiOrderChangeOut(List<EdiOrder> ediOrders) throws Exception {
		saveEdiOrder(ediOrders, false);
		//生成处理任务
		MdSendOutTask task = new MdSendOutTask();
		int qty = EdiOrderUtil.countOrderSkuQty(ediOrders);
		task.setCrTime(new Date());
		task.setDealStatus("0");
		task.setCustomerOrderNo(ediOrders.get(0).getCustomerOrdeno());
		task.setWorkNum(qty);
		task.setDoneNum(0);
		task.setDealCount(0);
		task.setOrderType(MDOrderType.CHANGEOUT.getType());
		mdSendOutTaskDao.save(task);
	}
	
	@Transactional(rollbackFor=Exception.class,readOnly = false)
	public void  saveEdiOrderReback(List<EdiOrder> ediOrders) throws Exception {
		saveEdiOrder(ediOrders, false);
		//生成处理任务
		MdSendOutTask task = new MdSendOutTask();
		int qty = EdiOrderUtil.countOrderSkuQty(ediOrders);
		task.setCrTime(new Date());
		task.setDealStatus("0");
		task.setCustomerOrderNo(ediOrders.get(0).getCustomerOrdeno());
		task.setWorkNum(qty);
		task.setDoneNum(0);
		task.setDealCount(0);
		task.setOrderType(MDOrderType.REBACK.getType());
		mdSendOutTaskDao.save(task);
	}

	@Transactional(rollbackFor = Exception.class, readOnly = false)
	public Map<String, Integer> getEdiOrderItems(List<EdiOrderItem> orderItems, String customerCode, String areagroupCode) {
		Map<String, Integer> maps = new HashMap<String, Integer>();
		for (EdiOrderItem ei : orderItems) {
			int qty = ei.getQty();// 待拣货的商品数量
			int indexCount = 0;
			
			//add by huwenjun 优化sql
			List list = loadStockByCondition(customerCode,areagroupCode,ei.getSku());
			if (list.isEmpty()) {
				return null;
			}
			Map row = (Map) list.get(0);
//			ViewCusStock viewCusStock = this.viewCusStockDao.loadStockByCondition(customerCode, areagroupCode, ei.getSku());
			indexCount = Integer.valueOf(row.get("sales_num").toString());
			CusStockMerge cusStockMerge = this.cusStockMergeDao.findCustomerWarSku(customerCode, areagroupCode, ei.getSku());
			if (cusStockMerge == null) {
//				indexCount = viewCusStock.getSalesNum();
				cusStockMerge = new CusStockMerge();
				cusStockMerge.setCustomerCode(customerCode);
				cusStockMerge.setWarehouseCode(areagroupCode);
				cusStockMerge.setOrderNum(0);
				cusStockMerge.setSku(ei.getSku());
				cusStockMerge.setLastmodifyTime(new Date());
				this.cusStockMergeDao.save(cusStockMerge);
			} else {
				indexCount = indexCount - cusStockMerge.getOrderNum();
			}

			if (indexCount < qty) {
				return null;
			}
			maps.put(ei.getSku(), qty);
		}
		return maps;
	}
	/**
	 * 订单处理时查询库存 by huwenjun
	 * @param customerCode
	 * @param areagroupCode
	 * @param sku
	 * @return
	 */
	private List loadStockByCondition(String customerCode,String areagroupCode,String sku) {
		Query querySql = em.createNativeQuery(
				"select "
				+"sql_no_cache `s`.`Id` AS `id`,`s`.`customer_code` AS `customer_code`,`s`.`warehouse_code` AS `warehouse_code`,`s`.`sku` AS `sku`,sum(`s`.`sales_num`) AS `sales_num` " 
				+"from "
				+"`cus_stock` `s` "
//				+"left join `cus_stock_safe` `sf` on `sf`.`sku` = `s`.`sku` and `sf`.`customer_code` = `s`.`customer_code` and `sf`.`warehouse_code` = `s`.`warehouse_code` "
//				+"left join `edi_goods_sku` `e` on `e`.`sku_id` = `s`.`sku` and `e`.`customer_code` = `s`.`customer_code` "
				+"where s.customer_code=?1 and s.warehouse_code=?2 and s.sku=?3 " 
				+"group by `s`.`warehouse_code`,`s`.`customer_code`,`s`.`sku`");
		querySql.setParameter(1, customerCode);
		querySql.setParameter(2, areagroupCode);
		querySql.setParameter(3, sku);
		querySql.unwrap(SQLQuery.class).setResultTransformer(Transformers.ALIAS_TO_ENTITY_MAP); 
		return querySql.getResultList();
	}
	@Transactional(readOnly = false, rollbackFor = Exception.class)
	public void disPatchOrder(DispatchOrderTask task, String node) {
		if (node != null && !node.equals(task.getDealIp())) {
			return;
		}
		task.setDealStatus(TaskStatus.SUCCESS.getStatus());
		EdiOrder order = findByOrderNoDetail(task.getOrderNo());
		if (StatusEnums.ORDER_STATUS_CANCEL.getStatus().equals(order.getOrderStatus()) || "1".equals(order.getDispatchFlag())) {
			return;
		}
		
		String disPatchWarehouseCode = order.getWarehouseCode();
		//查找有库存的分仓
		List<SubWarehouseRel> houseCodes = subWarehouseRelDao.findByMainWarehouseCode(order.getWarehouseCode());
		for (SubWarehouseRel subWareHouse : houseCodes) {
			Map<String, Integer> map = getEdiOrderItems(order.getOrderItems(), order.getCustomerCode(), subWareHouse.getSubWarehouseCode());
			if (map != null) {
				disPatchWarehouseCode = subWareHouse.getSubWarehouseCode();
				break;
			}
		}
		//如果分仓有货 先从分仓发
		if (!disPatchWarehouseCode.equals(order.getWarehouseCode())) {
			reMergeCusStock(order, disPatchWarehouseCode);
			updateEdiOrderDispatchFlag(order.getOrdeno(), disPatchWarehouseCode);
			logOrderCount.info("|{}|{}|{}|{}", order.getOrdeno(), disPatchWarehouseCode, order.getCustomerCode(), order.getCustomerOrdeno());
		} else {
			//查找主仓是否有库存
			if (WmsContants.CUSTOMER_MID.equals(order.getCustomerCode())) {
				Map<String, Integer> map = getEdiOrderItems(order.getOrderItems(), order.getCustomerCode(), order.getWarehouseCode());
				if (map != null) {
					updateEdiOrderDispatchFlag(order.getOrdeno(), disPatchWarehouseCode);
					// 美的 设置占用库存
					mergeCusStock(order, disPatchWarehouseCode, true);
					logOrderCount.info("|{}|{}|{}|{}", order.getOrdeno(), disPatchWarehouseCode, order.getCustomerCode(), order.getCustomerOrdeno());
				} else {
					// 没有库存，重置task
					task.setDealIp(null);
					task.setDealStatus(TaskStatus.UNHAND.getStatus());
				}
			} else {
				//美的之外的商家 不再判断主仓库存，订单流入时已做判断
				updateEdiOrderDispatchFlag(order.getOrdeno(), disPatchWarehouseCode);
				logOrderCount.info("|{}|{}|{}|{}", order.getOrdeno(), disPatchWarehouseCode, order.getCustomerCode(), order.getCustomerOrdeno());
			}
		}
	}
	
	/**
	 * 是否需要预先占用库存
	 * @param customerCode
	 * @return boolean
	 */
	public boolean ifMerge(String customerCode) {
		Customers customers = customersDao.findByCustomerCode(customerCode);
		return "1".equals(customers.getPlaceStatus()); 
	}
	
	/**
	 * 发货仓库变更后,重新设置库存占用,并返回之前仓库的占用量
	 * @param order
	 * @param disPatchWarehouseCode
	 */
	@Transactional(rollbackFor = Exception.class, readOnly = false)
	private void reMergeCusStock(EdiOrder order, String disPatchWarehouseCode) {
		// 设置sku占用的库存
		mergeCusStock(order, disPatchWarehouseCode, true);
		//返回之前占用的库存
		//美的推单没占用库存 不用返回
		if (!WmsContants.CUSTOMER_MID.equals(order.getCustomerCode())) {
			mergeCusStock(order, order.getWarehouseCode(), false);
		}
	}
	
	@Transactional(rollbackFor = Exception.class, readOnly = false)
	public void mergeCusStock(EdiOrder order, String warehouseCode, boolean addFlag) {
		if (!ifMerge(order.getCustomerCode())) {
			return;
		}
		for (EdiOrderItem orderItem : order.getOrderItems()) {
			CusStockMerge cusStockMerge = cusStockMergeDao.findCustomerWarSku(order.getCustomerCode(), warehouseCode, orderItem.getSku());
			if (cusStockMerge == null) {
				cusStockMerge = new CusStockMerge();
				cusStockMerge.setCustomerCode(order.getCustomerCode());
				cusStockMerge.setWarehouseCode(warehouseCode);
				cusStockMerge.setOrderNum(0);
				cusStockMerge.setSku(orderItem.getSku());
			}
			cusStockMerge.setLastmodifyTime(new Date());
			if (addFlag) {
				cusStockMerge.setOrderNum(cusStockMerge.getOrderNum() + orderItem.getQty());
			} else {
				cusStockMerge.setOrderNum(Math.max(cusStockMerge.getOrderNum() - orderItem.getQty(), 0));
			}
			cusStockMergeDao.save(cusStockMerge);
		}
	}

	@Transactional(rollbackFor = Exception.class, readOnly = false)
	public EdiOrder setAreaGroupCode(EdiOrder ediOrder) throws Exception {
		try {
			// 设置网点
			List<CustomerAreaGroup> lists = this.customerAreaGroupDao.findByCustomerCode(ediOrder.getCustomerCode());
			if (ediOrder.getProvco() != null) {
				for (CustomerAreaGroup list : lists) {
					String areaLists = list.getAreaLists();
					if (areaLists != null) {
						if (areaLists.indexOf(ediOrder.getProvco()) != -1) {
							ediOrder.setAreaGroupCode(list.getAreaGroupCode());
							break;
						}
					}
				}
			} else {
				ediOrder.setGymemo("0");
			}
			return ediOrder;
		} catch (Exception e) {
			throw e;
		}
	}

	/**
	 * OMS保存订单
	 * @param ediOrders
	 * @param customerCode
	 * @param warehouseCode
	 * @return
	 * @throws Exception
	 */
	@Transactional(rollbackFor = Exception.class, readOnly = false)
	public EdiOrder saveEdiOrderOMS(EdiOrder ediOrders, String customerCode, String warehouseCode) throws Exception {
		try {
			log.info("OMS订单流入");
			
			ShopSource shopSource = this.shopSourceDao.findByShopName(ediOrders.getShopna());
			if (shopSource == null) {
				ediOrders.setOrderStatus("no");
				ediOrders.setStatus("cancel");
				ediOrders.setMessage("店铺名称不存在");
				log.info("店铺名称不存在");
				return ediOrders;
			}
			ediOrders.setShopCode(shopSource.getShopCode());
			Date nowDate = new Date();
			Customers customers=this.customersDao.findByCustomerCode(customerCode);
			if ("1".equals(customers.getPlaceStatus())) {
				log.info("开始验证库存");
				Map<String, Integer> maps = setCusStock(ediOrders);
				if (maps == null) {
					ediOrders.setOrderStatus("no");
					ediOrders.setStatus("cancel");
					ediOrders.setMessage("库存不满足该订单");
					log.info("库存不满足该订单");
					return ediOrders;
				}
				log.info("库存验证成功");
			}
			
			List<EdiOrderItem> orderItems = ediOrders.getSkulst();
			int sku_num = 0;
			for (EdiOrderItem ei : orderItems) {
				ei.setCrtime(nowDate);
				int qty = ei.getQty();// 待拣货的商品数量
				sku_num += qty;
				if ("1".equals(customers.getPlaceStatus())) {
					CusStockMerge cusStockMerge = this.cusStockMergeDao.findCustomerWarSku(customerCode, ediOrders.getWarehouseCode(), ei.getSku());
					cusStockMerge.setOrderNum(cusStockMerge.getOrderNum() + qty);
					cusStockMerge.setLastmodifyTime(nowDate);
					this.cusStockMergeDao.save(cusStockMerge);
				}
				ei.setCustomerCode(customerCode);
				ei.setSku(ei.getSku().trim());
				ei.setOrdeno(ediOrders.getOrdeno());
				ediOrderItemDao.save(ei);
			}
			if (sku_num > 1) {
				ediOrders.setOrderType("multiple");
			} else {
				ediOrders.setOrderType("single");
			}
			ediOrders.setSkuQty(sku_num);
			ediOrders.setOrderStatus("ok");
			ediOrders.setStatus("pending");
			ediOrders.setErpType("oms");
			ediOrders.setCustomerOrdeno(ediOrders.getFromno());
			if(null==ediOrders.getCacode() || "null".equals(ediOrders.getCacode()))
			{
				ediOrders.setCacode("");
			}
			ediOrders.setIsdelv(false);// 分仓
			ediOrders.setGymemo("1");
			ediOrders.setAddres(ediOrders.getAddres());
			ediOrderDao.save(ediOrders);
			try {
				OrderLog orderLog = new OrderLog(ediOrders.getOrdeno(), ediOrders.getCustomerCode(), "0", null, new Date(), null, "系统接收订单");
				orderLogDao.save(orderLog);
			} catch (Exception e) {
				log.error("失败:", e);
			}
			return ediOrders;

		} catch (Exception e) {
			throw e;
		}
	}

	/**
	 * 重接失效订单
	 * @param id
	 * @return　true 成功，false 失败
	 * @throws Exception
	 */
	@Transactional(rollbackFor = Exception.class, readOnly = false)
	public int reUseEdiOrder(String id) throws Exception {
		try {
			log.info("重新处理失效订单");
			EdiOrder ediOrders = this.findOne(Long.parseLong(id));
			//@zwz
			if(!"ok".equals(ediOrders.getOrderStatus())) return -3;
			
			if(!"0".equals(ediOrders.getDispatchFlag()))return -2;
			List<EdiOrderItem> items = ediOrderItemDao.findByWaybillNo(ediOrders.getWaybillNo());
			ediOrders.setSkulst(items);
			Customers customers=this.customersDao.findByCustomerCode(ediOrders.getCustomerCode());
			if ("1".equals(customers.getPlaceStatus())) {
				log.info("开始验证库存");
				Map<String, Integer> maps = setCusStock(ediOrders);
				if (maps == null) {
//					ediOrders.setOrderStatus("no");
//					ediOrders.setStatus("cancel");
					ediOrders.setMessage("库存不满足该订单");
					log.info("库存不满足该订单");
					return -1;
				}
				
				log.info("库存验证成功");
			}
			
			List<EdiOrderItem> orderItems = ediOrders.getSkulst();
			int sku_num = 0;
			Date nowDate = new Date();
			for (EdiOrderItem ei : orderItems) {
				ei.setCrtime(nowDate);
				int qty = ei.getQty();// 待拣货的商品数量
				sku_num += qty;
				if ("1".equals(customers.getPlaceStatus())) {
					CusStockMerge cusStockMerge = this.cusStockMergeDao.findCustomerWarSku(ediOrders.getCustomerCode(), ediOrders.getWarehouseCode(), ei.getSku());
					cusStockMerge.setOrderNum(cusStockMerge.getOrderNum() + qty);
					cusStockMerge.setLastmodifyTime(nowDate);
					this.cusStockMergeDao.save(cusStockMerge);
				}

				ediOrderItemDao.save(ei);
			}
			ediOrders.setSkuQty(sku_num);
			ediOrders.setOrderStatus("ok");
			ediOrders.setStatus("pending");
			ediOrders.setDispatchFlag("1");
			ediOrderDao.save(ediOrders);
			ShiroUser curUser = (ShiroUser) SecurityUtils.getSubject().getPrincipal();
			User user=userDao.findOne(curUser.id);
			OrderLog orderLog = new OrderLog(ediOrders.getOrdeno(), ediOrders.getCustomerCode(), "0", null, new Date(), null, "尝试重新接收订单");
			orderLog.setOperater(user);
			orderLogDao.save(orderLog);		
			return 1;

		} catch (Exception e) {
			throw e;
		}
	}	
	
	
	/**
	 * 根据客户编码、仓库、开始日期、结束日期查询EdiOrder
	 * @param customerCode
	 * @param warehouseCode
	 * @param dateks
	 * @param datejs
	 * @return
	 */
		@Transactional(readOnly=true)
		public List<EdiOrder> findEdiOderByCWDD(String customerCode, String warehouseCode, String dateks, String datejs) {
			return ediOrderDao.findByEdiOrder(customerCode, warehouseCode, dateks, datejs);
		}
	
	
/**
 * 
 * @param ediOrders
 * @return
 */
	@Transactional(readOnly=true)
	private EdiOrder findEdiOrderById(EdiOrder ediOrders) {
		return ediOrderDao.findOne(ediOrders.getId());
	}
	
	
//	@Transactional(readOnly=false)
//	private int checkCusStock(EdiOrder ediOrders,int flag){
//		List<EdiOrderItem> items = ediOrderItemDao.findByWaybillNo(ediOrders.getWaybillNo());
//		ediOrders.setSkulst(items);
//		Customers customers = customersDao.findByCustomerCode(ediOrders.getCustomerCode());
//		int err = 0;
//		if ("1".equals(customers.getPlaceStatus())) {
//			log.info("开始验证库存");
//			Map<String, Integer> maps = setCusStock(ediOrders);
//			if (maps == null) {
//				ediOrders.setMessage("库存不满足该订单");
//				log.info("库存不满足该订单");
//				flag += 1;
//				err = 1;
//			}
//			log.info("库存验证成功");
//		}
//		if (err == 0) {
//			List<EdiOrderItem> orderItems = ediOrders.getSkulst();
//			int sku_num = 0;
//			Date nowDate = new Date();
//			for (EdiOrderItem ei : orderItems) {
//				ei.setCrtime(nowDate);
//				int qty = ei.getQty();// 待拣货的商品数量
//				sku_num += qty;
//				if (StringUtils.equals("1", customers.getPlaceStatus())) {
//					CusStockMerge cusStockMerge = cusStockMergeDao.findCustomerWarSku(ediOrders.getCustomerCode(),
//							ediOrders.getWarehouseCode(), ei.getSku());
//					cusStockMerge.setOrderNum(cusStockMerge.getOrderNum() + qty);
//					cusStockMerge.setLastmodifyTime(nowDate);
//					cusStockMergeDao.save(cusStockMerge);
//				}
//				ediOrderItemDao.save(ei);
//			}
//			ediOrders.setSkuQty(sku_num);
//			ediOrders.setOrderStatus("ok");
//			ediOrders.setStatus("pending");
//			ediOrders.setDispatchFlag("1");
//			ediOrderDao.save(ediOrders);
//			ShiroUser curUser = (ShiroUser) SecurityUtils.getSubject().getPrincipal();
//			User user = userDao.findOne(curUser.id);
//			OrderLog orderLog = new OrderLog(ediOrders.getOrdeno(), ediOrders.getCustomerCode(), "0", null, new Date(),
//					null, "尝试批量重新接收订单");
//			orderLog.setOperater(user);
//			orderLogDao.save(orderLog);
//		}
//		return flag;
//	}
	
	private List<String> getLaveCode(CustomerAreaGroup customerAreaGroup) {
		List<String> leves = new ArrayList<String>();
		String codes = customerAreaGroup.getGroupCodes();
		if (codes != null && (!"".equals(codes))) {
			String[] lists = codes.split(",");
			for (String list : lists) {
				leves.add(list);
			}
			Collections.sort(leves, new Comparator<String>() {
				public int compare(String arg0, String arg1) {
					String[] list0 = arg0.split(":");
					String[] list1 = arg1.split(":");
					return Integer.parseInt(list0[1]) - Integer.parseInt(list1[1]);
				}
			});
			return leves;
		} else {
			return null;
		}

	}

	/**
	 * 设置作业仓库库存
	 * @param ediOrders
	 */
	@Transactional(rollbackFor = Exception.class, readOnly = false)
	public Map<String, Integer> setCusStock(EdiOrder ediOrders) {
		List<EdiOrderItem> orderItems = ediOrders.getSkulst() == null ? ediOrders.getOrderItems() : ediOrders.getSkulst();
		String tempCode = ediOrders.getWarehouseCode();
		Map<String, Integer> maps = getEdiOrderItems(orderItems, ediOrders.getCustomerCode(), ediOrders.getWarehouseCode());
		if (maps == null) {
			log.info("CustomerCode:{} WarehouseCode :{} fromNo :{} ===", ediOrders.getCustomerCode(), ediOrders.getWarehouseCode(),ediOrders.getFromno());
			CustomerAreaGroup customerAreaGroup = this.customerAreaGroupDao.findByCustomerCodeAndAreaGroupCode(ediOrders.getCustomerCode(), ediOrders.getWarehouseCode());
			List<String> leves = getLaveCode(customerAreaGroup);
			if (leves == null) {
				return null;
			}
			for (String leve : leves) {
				String[] lists = leve.split(":");
				String wareHouseCode = lists[0];
				if (tempCode.equals(wareHouseCode)) {
					continue;
				}
				log.info("{} reset warehousecode:{}" ,ediOrders.getFromno(), wareHouseCode);
				ediOrders.setWarehouseCode(wareHouseCode);
				maps = getEdiOrderItems(orderItems, ediOrders.getCustomerCode(), ediOrders.getWarehouseCode());
				if (maps != null) {
					return maps;
				} else {
					log.info("{} rollback warehousecode:{}" ,ediOrders.getFromno(), tempCode);
					ediOrders.setWarehouseCode(tempCode);
				}
			}
		}
		return maps;
	}

	@Transactional(rollbackFor = Exception.class, readOnly = false)
	public EdiOrder saveEdiOrderPlat(EdiOrder ediOrders) throws Exception {
			if ("no".equals(ediOrders.getOrderStatus())) {
				log.info("不属于本系统处理的订单");
				// saveEdiOrder(ediOrders);
				return ediOrders;
			}
			
			if(StringUtils.isBlank(ediOrders.getProvco()) || StringUtils.isBlank(ediOrders.getProvna())
					|| StringUtils.isBlank(ediOrders.getCityna()))
			{
				ediOrders.setStatus("cancel");
				ediOrders.setMessage("省份编码和省市名称不能为空");
				return ediOrders;
			}

			// 美丽说处理
			List<EdiOrder> ediOrder1 = ediOrderDao.findByCustomerCodeAndCustomerOrdenoAndOrderStatus(ediOrders.getCustomerCode(), ediOrders.getCustomerOrdeno());
			if (!ediOrder1.isEmpty()) {
				ediOrders.setStatus("repeat");
				ediOrders.setMessage("订单重复流入");
				return ediOrders;
			}

			Customers customers = customersDao.findByCustomerCode(ediOrders.getCustomerCode());
			List<AreaGroup> areaGroups = this.areaGroupDao.loadByCustomerCode(ediOrders.getCustomerCode());

			if ("1".equals(customers.getSectionPo())) {// 分仓宝
				if (ediOrders.getAreaGroupCode() == null) {
					ediOrders.setOrderStatus("no");
					return ediOrders;
				} else {
					ediOrders.setWarehouseCode(ediOrders.getAreaGroupCode());// 分仓优先
				}
			} else {
				if (!areaGroups.isEmpty()) {
					ediOrders.setWarehouseCode(areaGroups.get(0).getGroupCode());
				} else {
					throw new Exception("没有商家仓");
				}
			}

			if ("0".equals(customers.getPlaceStatus())) {
				log.info("不限制订单流入");
				saveEdiOrder(ediOrders);
				return ediOrders;
			}

			log.info("开始验证库存");
			Map<String, Integer> maps = setCusStock(ediOrders);
			if (maps == null) {
				ediOrders.setOrderStatus("no");
				ediOrders.setStatus("cancel");
				ediOrders.setMessage("库存不满足该订单");
				log.info("库存不满足该订单");
				return ediOrders;
			}
			log.info("库存验证成功");
			try {
				ediOrders = margeOrdeno(ediOrders);
			} catch (Exception e) {
				throw new Exception("合并订单出错:" + e);
			}

			if (null == ediOrders.getOrdeno()) {
				CreateOrdeno.setOrdenrOrdeno(ediOrders, tMSRule);// 能容订单号赋值
			}
			if (ediOrders.getWaybillNo() == null) {
				ediOrders.setWaybillNo(tMSRule.getNumber(ediOrders.getCustomerCode()));
			}
			log.info("开始保存订单申请的订单号为:" + ediOrders.getOrdeno());
			StringBuffer sb = new StringBuffer();
			Date nowDate = new Date();
			List<EdiOrderItem> orderItems = ediOrders.getSkulst();
			for (EdiOrderItem ei : orderItems) {
				ei.setCrtime(nowDate);
				int qty = ei.getQty();// 待拣货的商品数量
				CusStockMerge cusStockMerge = this.cusStockMergeDao.findCustomerWarSku(ediOrders.getCustomerCode(), ediOrders.getWarehouseCode(), ei.getSku());
				cusStockMerge.setOrderNum(cusStockMerge.getOrderNum() + qty);
				cusStockMerge.setLastmodifyTime(nowDate);
				this.cusStockMergeDao.save(cusStockMerge);
				ei.setWaybillNo(ediOrders.getWaybillNo());
				ei.setCustomerCode(ediOrders.getCustomerCode());
				ediOrderItemDao.save(ei);
			}

			log.info("申请的运单号为:" + ediOrders.getWaybillNo());
			ediOrders.setPickStore(sb.toString());
			ediOrders.setIsdelv(false);// 分仓
			ediOrders.setGymemo("1");
			ediOrderDao.save(ediOrders);
			// SaveEdiOrdenoRedis.saveRedis(redisEdiOrdenoService, ediOrders);
			try {
				OrderLog orderLog = new OrderLog(ediOrders.getOrdeno(), ediOrders.getCustomerCode(), "0", null, new Date(), null, "系统接收订单");
				orderLogDao.save(orderLog);
			} catch (Exception e) {
				log.error("失败:", e);
			}
			return ediOrders;

	}

	public List<EdiOrder> findByCrtime(String crtime) {
		return ediOrderDao.findByCrtime(crtime);
	}

	@Transactional(rollbackFor = Exception.class, readOnly = false)
	public void saveException(List<EdiOrder> ediOrders) throws Exception {
		if (ediOrders == null) {
			return;
		}
		ediOrderDao.save(ediOrders);
		for (int i = 0; i < ediOrders.size(); i++) {
			EdiOrder ediOrder = ediOrders.get(i);
			List<EdiOrderItem> ediOrderItems = ediOrders.get(i).getSkulst();
			if (ediOrderItems != null) {
				if (ediOrderItems.size() == 1) {
					EdiOrderItem ediOrderItem = ediOrderItems.get(0);
					if (ediOrderItem.getQty() > 1) {
						ediOrder.setOrderType("multiple");
					} else {
						ediOrder.setOrderType("single");
					}
				} else {
					ediOrder.setOrderType("multiple");
				}
				ediOrderDao.save(ediOrder);// 保存订单状态
				for (int j = 0; j < ediOrderItems.size(); j++) {
					EdiOrderItem ediOrderItem = ediOrderItems.get(j);
					String ordeno = ediOrder.getOrdeno();
					ediOrderItem.setOrdeno(ordeno);
				}
				ediOrderItemDao.save(ediOrderItems);// 保存订单明细
			}
		}
		ediOrderDao.save(ediOrders);
	}

	@Transactional(readOnly = false)
	public void regainOrdeno(Long id) {
		EdiOrder e = findOne(id);
		e.setOrderStatus("ok");
		e.setStatus("pending");
		ediOrderDao.save(e);
	}

	public EdiOrder findOne(Long orderId) {
		if (orderId == null) {
			throw new IllegalArgumentException("orderId=" + orderId);
		}
		return ediOrderDao.findOne(orderId);
	}

	public List<EdiOrder> crTimeHoursLists(String dataString, String endString, Map<String, Object> filterParams) {
		Specification<EdiOrder> spec = buildSpecificationHours(dataString, endString, filterParams);
		return ediOrderDao.findAll(spec);
	}

	public List<EdiOrder> crTimeHoursLists(Map<String, Object> filterParams) {
		Specification<EdiOrder> spec = buildSpecificationHours(filterParams);
		return ediOrderDao.findAll(spec);
	}

	private Specification<EdiOrder> buildSpecificationHours(Map<String, Object> filterParams) {
		Map<String, SearchFilter> filters = SearchFilter.parse(filterParams);
		Specification<EdiOrder> spec = DynamicSpecifications.bySearchFilter(filters.values(), EdiOrder.class);
		return spec;
	}

	public Page<EdiOrder> pageOrders(Map<String, Object> filterParams, int pageNumber, int pageSize, String sortType, String dataString, String endString) {
		PageRequest pageRequest = buildPageRequest(pageNumber, pageSize, sortType);
		Specification<EdiOrder> spec = buildSpecificationHours(dataString, endString, filterParams);
		Page<EdiOrder> ediOrders = ediOrderDao.findAll(spec, pageRequest);
		return ediOrders;
	}

	/**
	 * 创建动态查询条件组合.
	 */
	private Specification<EdiOrder> buildSpecificationHours(String firstString, String endString, Map<String, Object> filterParams) {
		Map<String, SearchFilter> filters = SearchFilter.parse(filterParams);
		filters.put("crtimeGTE", new SearchFilter("crtime", Operator.GTE, firstString));
		filters.put("crtimeLT", new SearchFilter("crtime", Operator.LT, endString));
		Specification<EdiOrder> spec = DynamicSpecifications.bySearchFilter(filters.values(), EdiOrder.class);
		return spec;
	}

	public List<EdiOrder> crTimeLists(String dataString, Map<String, Object> filterParams) {
		Specification<EdiOrder> spec = buildSpecification(dataString, filterParams);
		return ediOrderDao.findAll(spec);
	}

	public List<EdiOrder> crTimeLists(Map<String, Object> filterParams) {
		Specification<EdiOrder> spec = buildSpecification(filterParams, EdiOrder.class);
		return ediOrderDao.findAll(spec);
	}

	public Page<EdiOrder> crTimeLists(Map<String, Object> filterParams, int pageNumber, int pagzSize) {
		PageRequest pageRequest = buildPageRequestMouth(pageNumber, pagzSize);
		Specification<EdiOrder> spec = buildSpecification(filterParams, EdiOrder.class);
		return ediOrderDao.findAll(spec, pageRequest);
	}

	/**
	 * 创建分页请求.
	 */
	private PageRequest buildPageRequestMouth(int pageNumber, int pagzSize) {
		return new PageRequest(pageNumber - 1, pagzSize);
	}

	/**
	 * 创建动态查询条件组合.
	 */
	private Specification<EdiOrder> buildSpecification(String dataString, Map<String, Object> filterParams) {
		Map<String, SearchFilter> filters = SearchFilter.parse(filterParams);
		filters.put("crtime", new SearchFilter("crtime", Operator.GTE, dataString));
		Specification<EdiOrder> spec = DynamicSpecifications.bySearchFilter(filters.values(), EdiOrder.class);
		return spec;
	}

	public List<EdiOrder> findAll() {
		return (List<EdiOrder>) ediOrderDao.findAll();
	}
	
	@PersistenceContext
	private EntityManager em;
	
	public List<EdiOrder> findByProvco(String provco) {
		return (List<EdiOrder>) ediOrderDao.findByProvco(provco);
	}
	
	public Map<String,List<EdiOrder>> loadUnhandledOrderNew(Map<String, Object> searchParams, String tacticsType) throws Exception {
		List<EdiOrder> _singleOrderList = new ArrayList<EdiOrder>();
		List<EdiOrder> _multiOrderList = new ArrayList<EdiOrder>();
		
		String mergeOrder = (String)searchParams.get("mergeOrder");
		if("true".equals(mergeOrder)){
			//所有
			List<EdiOrder> allOrderList = loopEdiOrder(searchParams);
			if(allOrderList.size()==0){
				Map<String, List<EdiOrder>> result = new HashMap<String, List<EdiOrder>>();
				result.put("allOrderList", allOrderList);
				
				return result;
			}
			//插入ediOrderItem信息
			List<String> ordenos = new ArrayList<String>();
			for(EdiOrder ediOrder:allOrderList){
				ordenos.add(ediOrder.getOrdeno());
			}
			
			Map<String,List<EdiOrderItem>> itemMap = new HashMap<String,List<EdiOrderItem>>();
			List<EdiOrderItem> items = ediOrderItemDao.findByOrderno(ordenos);
			for(EdiOrderItem item:items) {
				if(itemMap.containsKey(item.getOrdeno())){
					List<EdiOrderItem> ils = itemMap.get(item.getOrdeno());
					ils.add(item);
				}else {
					List<EdiOrderItem> ils = new ArrayList<EdiOrderItem>();
					ils.add(item);
					itemMap.put(item.getOrdeno(), ils);
					
				}
			}
			for(EdiOrder ediOrder:allOrderList){
				List<EdiOrderItem> itemList = itemMap.get(ediOrder.getOrdeno());
				ediOrder.setOrderItems(itemList);
			}
			
			Map<String, List<EdiOrder>> result = new HashMap<String, List<EdiOrder>>();
			result.put("allOrderList", allOrderList);
			return result;
		}else {
			//单件
			searchParams.put("orderType", "single");
			List<EdiOrder> singleOrderList = loopEdiOrder(searchParams);
			//多件
			searchParams.put("orderType", "multiple");
			List<EdiOrder> multiOrderList = loopEdiOrder(searchParams);
			//插入ediOrderItem信息
			List<String> ordenos = new ArrayList<String>();
			for(EdiOrder ediOrder:singleOrderList){
				ordenos.add(ediOrder.getOrdeno());
			}
			for(EdiOrder ediOrder:multiOrderList){
				ordenos.add(ediOrder.getOrdeno());
			}
			
			Map<String,List<EdiOrderItem>> itemMap = new HashMap<String,List<EdiOrderItem>>();
			if(ordenos.size() > 0){
				List<EdiOrderItem> items = ediOrderItemDao.findByOrderno(ordenos);
				for(EdiOrderItem item:items) {
					if(itemMap.containsKey(item.getOrdeno())){
						List<EdiOrderItem> ils = itemMap.get(item.getOrdeno());
						ils.add(item);
					}else {
						List<EdiOrderItem> ils = new ArrayList<EdiOrderItem>();
						ils.add(item);
						itemMap.put(item.getOrdeno(), ils);
						
					}
				}
				
				for(EdiOrder ediOrder:singleOrderList){
					List<EdiOrderItem> itemList = itemMap.get(ediOrder.getOrdeno());
					ediOrder.setOrderItems(itemList);
				}
				for(EdiOrder ediOrder:multiOrderList){
					List<EdiOrderItem> itemList = itemMap.get(ediOrder.getOrdeno());
					ediOrder.setOrderItems(itemList);
				}
				// 策略排序
				_singleOrderList = sortByTactics(tacticsType, "single", singleOrderList);
				_multiOrderList = sortByTactics(tacticsType, "multi", multiOrderList);
			}
			
	
			Map<String, List<EdiOrder>> result = new HashMap<String, List<EdiOrder>>();
			result.put("single", _singleOrderList);
			result.put("multi", _multiOrderList);
			
			return result;
		}
		
	}
	
	public List<EdiOrder> loopEdiOrder(Map<String, Object> searchParams) throws Exception {
		List<EdiOrder> ediOrderList  = new ArrayList<EdiOrder>();
		
		Specification<EdiOrder> spec = getWhereClause(searchParams);
		int pageNumber = 1;
		int pageSize = 500;
		while(true){
			PageRequest pageRequest = buildPageRequest(pageNumber, pageSize, "crtime_asc");
			Page<EdiOrder> pageEdiOrderList = this.ediOrderDao.findAll(spec,pageRequest);
			if(pageEdiOrderList.getContent().size()==0){
				break;
			}
			
			//如果有重量范围参数，则
			
			Integer minWeight = null;
			Integer maxWeight = null;
			try{
				minWeight = Integer.valueOf((String)searchParams.get("minWeight"));
//				maxWeight = Integer.valueOf((String)searchParams.get("maxWeight"));
			}catch(Exception e){}
			try{
				maxWeight = Integer.valueOf((String)searchParams.get("maxWeight"));
			}catch(Exception e){}
			List<EdiOrder> ediOrderContent  = null;
			if((minWeight != null && minWeight != 0)||(maxWeight != null && maxWeight != 0)){
				ediOrderContent = new ArrayList<EdiOrder>();
				for(EdiOrder ediOrder:pageEdiOrderList.getContent()){
					int weight = 0;
					List<EdiOrderItem> items = ediOrderItemDao.findByOrdeno(ediOrder.getOrdeno());
					for (EdiOrderItem ediOrderItem : items) {
						EdiGoodsSku ediGoodsSku = ediGoodsSkuDao.findByCustomerCodeAndSku(ediOrderItem.getCustomerCode(), ediOrderItem.getSku());
						if(ediGoodsSku.getWeight()==null){
							ediGoodsSku.setWeight(0);
						}
						if(ediGoodsSku.getWeightPkg()==null){
							ediGoodsSku.setWeightPkg(0);
						}
						if(ediOrderItem.getQty()==null){
							ediOrderItem.setQty(0);
						}
						if(ediGoodsSku!=null){
							weight += (ediGoodsSku.getWeight()+ediGoodsSku.getWeightPkg())*ediOrderItem.getQty();
						}
						if(!"0".equals(ediOrderItem.getSellFlg()) && StringUtils.isEmpty(ediOrder.getSku()) ){
							ediOrder.setSku(ediOrderItem.getSku());
						}
					}
					if((minWeight != null && minWeight != 0)&&(maxWeight != null && maxWeight != 0)){
						if((minWeight <= weight  && weight <= maxWeight)){
							ediOrder.setTotalWeight(weight);
							ediOrderContent.add(ediOrder);
						}
					}else if((minWeight != null && minWeight != 0)){
						if(minWeight <= weight){
							ediOrder.setTotalWeight(weight);
							ediOrderContent.add(ediOrder);
						}
					}
					else if((maxWeight != null && maxWeight != 0)){
						if(maxWeight >= weight){
							ediOrder.setTotalWeight(weight);
							ediOrderContent.add(ediOrder);
						}
					}
				}
			}else {
			    if("1".equals(searchParams.get("dealType"))){
    			    StringBuffer orderBuffer=new StringBuffer();
                    for (EdiOrder ediOrder:pageEdiOrderList.getContent()) {
                        orderBuffer.append("'" + ediOrder.getOrdeno() + "'").append(",");
                    }
                    List<Map<String, Object>> tmeps = loadWeightAndSku(orderBuffer.toString()+"''");
                    Map<String, Integer> weightMap= new HashMap<String, Integer>();
                    Map<String, String> skuMap= new HashMap<String, String>();
                    for (Map<String, Object> map : tmeps) {
                        weightMap.put(map.get("ordeno").toString(), Integer.valueOf(map.get("num").toString()));
                        skuMap.put(map.get("ordeno").toString(), map.get("sku").toString());
                    }
                    for (EdiOrder ediOrder:pageEdiOrderList.getContent()) {
                        ediOrder.setTotalWeight(weightMap.get(ediOrder.getOrdeno()));
                        if(StringUtils.isEmpty(ediOrder.getSku()) && !StringUtils.isEmpty(skuMap.get(ediOrder.getOrdeno())) ){
                            ediOrder.setSku(skuMap.get(ediOrder.getOrdeno()));
                        }
                    }
			    }else{
    				for(EdiOrder ediOrder:pageEdiOrderList.getContent()){
    					int weight = 0;
    					List<EdiOrderItem> items = ediOrderItemDao.findByOrdeno(ediOrder.getOrdeno());
    					for (EdiOrderItem ediOrderItem : items) {
    						EdiGoodsSku ediGoodsSku = ediGoodsSkuDao.findByCustomerCodeAndSku(ediOrderItem.getCustomerCode(), ediOrderItem.getSku());
    						if(ediGoodsSku!=null){
    							if(ediGoodsSku.getWeight()==null){
    								ediGoodsSku.setWeight(0);
    							}
    							if(ediGoodsSku.getWeightPkg()==null){
    								ediGoodsSku.setWeightPkg(0);
    							}
    							if(ediOrderItem.getQty()==null){
    								ediOrderItem.setQty(0);
    							}
    							weight += (ediGoodsSku.getWeight()+ediGoodsSku.getWeightPkg())*ediOrderItem.getQty();
    						}
    						if(!"0".equals(ediOrderItem.getSellFlg()) && StringUtils.isEmpty(ediOrder.getSku()) ){
    							ediOrder.setSku(ediOrderItem.getSku());
    						}
    					}
    					ediOrder.setTotalWeight(weight);
    				}
			    }
				ediOrderContent = pageEdiOrderList.getContent();
			}
			
			//change by huwenjun 取消查询时去查询超区件
//			List<EdiOrder> orderList  = new ArrayList<EdiOrder>();
//			orderList = filterOutScope(ediOrderContent, searchParams);
			pageNumber++;
			ediOrderList.addAll(ediOrderContent);
			if(ediOrderList.size()>=1000){
				ediOrderList = ediOrderList.subList(0,1000);
				break;
			}
		}
		return ediOrderList;
	}
	
	/**
     * 查询订单的总重量和非赠品的SKU
     * 
     * @param ordenos 订单组合
     * @return 
     * @throws 
     * @author <a href=mailto:libin@nryuncang.com>libin</a>
     * @version 1.0.0
	 * @throws Exception 
     */
    public List<Map<String, Object>> loadWeightAndSku(String ordenos) throws Exception {
        
        try {
            String sql ="select a.ordeno ,sum((ifnull(c.weight,0) + ifnull(c.weight_pkg,0)) * ifnull(b.qty,0)) num ,"
                    + " case left(max(concat(ifnull(b.sell_flg,'1'),b.sku_id)),1) when '1' then max(concat(ifnull(b.sell_flg,'1'),b.sku_id)) else '' end sku"
                    + " from edi_order a left join edi_order_item b on a.ordeno = b.ordeno left join edi_goods_sku c on c.sku_id=b.sku_id and c.customer_code=a.customer_code"
                    + " where a.ordeno in(" + ordenos + ")" + " group by a.ordeno";
            return jdbcTemplate.queryForList(sql);
        } catch (Exception e) {
            log.info("查询订单的总重量错误{}",e);
            throw new Exception("查询订单的总重量错误");
        }
    }
	
	/**
	 * 作废
	 * @param ediOrderList
	 * @param searchParams
	 * @return
	 */
	public List<EdiOrder> filterOutScope(List<EdiOrder> ediOrderList,Map<String, Object> searchParams) {
		String scopeFilter = (String) searchParams.get("scopeFilter");
		
		List<EdiOrder> allOrderList_outScope = new ArrayList<EdiOrder>(); // 超区件
		List<EdiOrder> allOrderList_not_outScope = new ArrayList<EdiOrder>(); // 非超区件
		
		// 判断是否是超区件
		for (EdiOrder eOrder : ediOrderList) {
			String companyCode = eOrder.getCacode();
			String warehouseCode = eOrder.getWarehouseCode();
			String queryCaCode = (String) searchParams.get("companyCode");
			String queryPsCaCode = (String) searchParams.get("psCompanyCode");
			if ("-1".equals(queryCaCode)) {// 指定
				if (StringUtils.isBlank(companyCode)||"OTHER".equals(companyCode)) {
					continue;
				}
			} else if ("-2".equals(queryCaCode)) {// 未指定
				if (!StringUtils.isBlank(companyCode)&&!"OTHER".equals(companyCode)) {
					continue;
				}
				companyCode = queryPsCaCode;
			} else if ("".equals(queryCaCode)) {//全部
				
			}else {
				companyCode = queryPsCaCode;
			}

			// 发票
			String isInvoice = (String) searchParams.get("isInvoice");
			if ("1".equals(isInvoice)) {// 需要发票
				if (!eOrder.getIsInvoice()) {
					continue;
				}
			} else if ("2".equals(isInvoice)) {// 不需要发票
				if (eOrder.getIsInvoice()) {
					continue;
				}
			}

			//1指定快递未超区  2未指定快递 超区件  3未指定快递优势区 
			if("1".equals(scopeFilter)||"2".equals(scopeFilter)) {
				//会过滤掉超区件
				String address = eOrder.getAddres() == null ? "" : eOrder.getAddres();
				List<OutScope> outScopeList = this.outScopeDao.loadByCompanyCode(companyCode,warehouseCode);
				String zoneFullName;
				int idx;
				boolean flag = true;
				for (OutScope os : outScopeList) {
					List<ScopeCustomerConfig> configList = os.getCustomerConfigList();
					boolean existsCustomerCode = false;
					for(ScopeCustomerConfig config:configList){
						if(config.getCustomerCode().equals(eOrder.getCustomerCode())){
							existsCustomerCode = true;
							break;
						}
					}
					if(existsCustomerCode){
						continue;
					}
					zoneFullName = os.getZoneFullName();
					idx = address.indexOf(zoneFullName);
					if (idx >= 0) { // 超区件
						allOrderList_outScope.add(eOrder);
						flag = false;
						break;
					}
				}
				//wms已配置超区，按wms超区过滤。否则调用外部接口
				/*if (flag && DOPConstans.LOGISTIC_PROVIDERID_CODE.equals(companyCode)) {
					flag = depponService.checkArrive(eOrder);
					if (!flag) {
						allOrderList_outScope.add(eOrder);
					}
				}*/
				//wms已配置超区，按wms超区过滤。否则调用TTKDEX接口
				if (flag && "TTKDEX".equals(companyCode)) {
					flag = ttkdexService.checkArrive(eOrder);
					if (!flag) {
						allOrderList_outScope.add(eOrder);
					}
				}
				if (flag && "YUNDA".equals(companyCode)) {
					flag = yundaService.checkArrive(eOrder);
					if (!flag) {
						allOrderList_outScope.add(eOrder);
					}
				}
				if (flag) { // 非超区件
					allOrderList_not_outScope.add(eOrder);
				}
			}else  {
				//会过赛选优势区
				String address = eOrder.getAddres() == null ? "" : eOrder.getAddres();
				String zoneFullName;
				int idx;
				boolean inFlg = false;
				List<InScope> inScopeList = this.inScopeDao.loadByCompanyCode(companyCode,warehouseCode);
				for (InScope os : inScopeList) {
					List<ScopeCustomerConfig> configList = os.getCustomerConfigList();
					boolean existsCustomerCode = false;
					for(ScopeCustomerConfig config:configList){
						if(config.getCustomerCode().equals(eOrder.getCustomerCode())){
							existsCustomerCode = true;
							break;
						}
					}
					if(existsCustomerCode){
						continue;
					}
					zoneFullName = os.getZoneFullName();
					idx = address.indexOf(zoneFullName);
					if (idx >= 0) { // 优势区
						inFlg = true;
						break;
					}
				}
				if(inFlg){
					allOrderList_not_outScope.add(eOrder);
				}
			}
		}
		
		
		if("2".equals(scopeFilter)){
			return allOrderList_outScope;
		}else {
			return allOrderList_not_outScope;
		}
	}
	
	/**
	 * 查询没有处理过区域等级的订单
	 * @return
	 */
	public List<EdiOrderVO> findListByRlIsNull() {
		try {
		Query querySql = em.createNativeQuery(
				"select t.id,t.cacode,t.warehouse_code,t.ordeno,"
				+ "t.provna,t.cityna,t.distna,t.addres,t.customer_code from edi_order t "
				+ "where t.regional_level is null order by t.id limit ?1");
		querySql.setParameter(1, 1999);
		querySql.unwrap(SQLQuery.class).setResultTransformer(Transformers.ALIAS_TO_ENTITY_MAP);  
		List<EdiOrderVO> resultList = new ArrayList<EdiOrderVO>();
		List list = querySql.getResultList();
		for (Object obj : list) {
	        Map row = (Map) obj;
			EdiOrderVO vo = new EdiOrderVO();
			vo.setId(Integer.valueOf(row.get("id").toString()));
			if(row.get("cacode") != null)
				vo.setCacode(row.get("cacode").toString());
			if(row.get("warehouse_code") != null)
				vo.setWarehouse_code(row.get("warehouse_code").toString());
			if(row.get("ordeno") != null)
				vo.setOrdeno(row.get("ordeno").toString());
			if(row.get("provna") != null)
				vo.setProvna(row.get("provna").toString());
			if(row.get("cityna") != null)
				vo.setCityna(row.get("cityna").toString());
			if(row.get("distna") != null)
				vo.setDistna(row.get("distna").toString());
			if(row.get("addres") != null)
				vo.setAddres(row.get("addres").toString());
			vo.setCustomer_code(row.get("customer_code").toString());
			resultList.add(vo);
		}
		return resultList;
		} catch(Exception e) {
			e.printStackTrace();
		}
		return null;
	}
	/**
	 * 超区判断 Table edi_order.regional_level
	 * @param ediOrder
	 * @author huwenjun
	 * @return
	 */
	@Transactional(readOnly = false, rollbackFor = Exception.class)
	public void filterOutScope(EdiOrderVO eOrder) {
		//物流公司编码
		String companyCode = eOrder.getCacode();
		//作业仓库网点
		// String warehouseCode = eOrder.getWarehouse_code();//.getWarehouseCode();
		//超区判断
		if ("TTKDEX".equals(companyCode)) {
		    //如果是天天快递，则调用天天的超区查询接口
		    Map<String, Integer> ttArrive = ttkdexService.checkArrive(eOrder);
		    if (ttArrive != null) {
		        // 天天接口返回，没有异常
	            if(1 == ttArrive.get("arrive")) {
	                //可达区域
	                this.ediOrderDao.updateEdiOrderRegionalLevel(eOrder.getId().longValue(), 1);
	            } else {
	                //超区
	                this.ediOrderDao.updateEdiOrderRegionalLevel(eOrder.getId().longValue(), 2);
	            }
            }else{
                // 天天超区接口异常 先访问菜鸟超区判断接口 如果菜鸟接口异常 使用本地配置
                String ttCode = "504"; // 天天快递在菜鸟中的编码,可通过AliLogisticsAPIUtils.companiesInfo获取
                // 拼接地址
                String address = "";
                if (StringUtils.isNotBlank(eOrder.getProvna())) {
                    address += eOrder.getProvna();
                }
                if (StringUtils.isNotBlank(eOrder.getCityna())) {
                    address += eOrder.getCityna();
                }
                if (StringUtils.isNotBlank(eOrder.getDistna())) {
                    address += eOrder.getDistna();
                }
                if (StringUtils.isNotBlank(eOrder.getAddres())) {
                    address += eOrder.getAddres();
                }
                Map<String, Integer> result = AliLogisticsAPIUtils.reachable(ttCode, address);
                if(result != null){
                    // 菜鸟成功回传
                    if (AliLogisticsAPIUtils.ReachableEnum.UN_REACHABLE.getCode() == result.get(ttCode)) {
                        // 超区件
                        ediOrderDao.updateEdiOrderRegionalLevel(eOrder.getId().longValue(), 2);
                    } else {
                        // 其他都为不超区 = 1 2 3
                        ediOrderDao.updateEdiOrderRegionalLevel(eOrder.getId().longValue(), 1);
                    }
                } else {
                    // 菜鸟回传失败,走本地配置
                    updateRegionalLevelByLocalConfig(eOrder);
                }
            }
		    
		} else {
			//非天天快递，查询本地超区配置
			updateRegionalLevelByLocalConfig(eOrder);
		}
	}
	
	/**
	 * 根据本地配置更新订单超区信息
	 *
	 * @param 
	 * @return 
	 * @throws 
	 * @author yuansheng
	 * @version 1.0.0
	 */
	private void updateRegionalLevelByLocalConfig(EdiOrderVO eOrder){
	    String address = eOrder.getAddres() == null ? "" : eOrder.getAddres();
        List<OutScope> outScopeList = this.outScopeDao.loadByCompanyCode(eOrder.getCacode(),eOrder.getWarehouse_code());
        String zoneFullName;
        int idx;
        boolean flag = true;
        for (OutScope os : outScopeList) {
            List<ScopeCustomerConfig> configList = os.getCustomerConfigList();
            boolean existsCustomerCode = false;
            for(ScopeCustomerConfig config:configList){
                if(config.getCustomerCode().equals(eOrder.getCustomer_code())){
                    existsCustomerCode = true;
                    break;
                }
            }
            if(existsCustomerCode){
                continue;
            }
            zoneFullName = os.getZoneFullName();
            idx = address.indexOf(zoneFullName);
            if (idx >= 0) { // 超区件
                flag = false;
                break;
            }
        }
        log.info("系统判定订单超区类型：{}",flag);
        if (flag) { // 可达区域
            ediOrderDao.updateEdiOrderRegionalLevel(eOrder.getId().longValue(), 1);
        } else { //超区，配置中超区或数据异常（快递公司编码为空值、超区表中查询不到）都属于超区
            ediOrderDao.updateEdiOrderRegionalLevel(eOrder.getId().longValue(), 2);
        }
	}
	
	/**
	 * 查找待处理的订单
	 * @param tacticsType 策略类型　timefirst: 时间优先策略   skufirst:sku集中策略    fix:组合策略  onesku: 单品合拣
	 * @return
	 * @throws Exception
	 */
	public Map<String, List<EdiOrder>> loadUnhandledOrder(Map<String, Object> searchParams, String tacticsType) throws Exception {
		List<EdiOrder> singleOrderList = new ArrayList<EdiOrder>();
		List<EdiOrder> multiOrderList = new ArrayList<EdiOrder>();

		// 查出所有订单
		Specification<EdiOrder> spec = getWhereClause(searchParams);
		List<EdiOrder> allOrderList = this.ediOrderDao.findAll(spec);
		

		List<EdiOrder> allOrderList_outScope = new ArrayList<EdiOrder>(); // 超区件
		List<EdiOrder> allOrderList_not_outScope = new ArrayList<EdiOrder>(); // 非超区件
		
		String scopeFilter = (String) searchParams.get("scopeFilter");
		
		// 判断是否是超区件
		for (EdiOrder eOrder : allOrderList) {
			//change by huwenjun
			//注释掉原有的超区判断，修改为新逻辑
			if(eOrder.getRegionalLevel() == 2)
				allOrderList_outScope.add(eOrder);
			if(eOrder.getRegionalLevel() == 1)
				allOrderList_not_outScope.add(eOrder);
//			String companyCode = eOrder.getCacode();
//			String warehouseCode = eOrder.getWarehouseCode();
//			String queryCaCode = (String) searchParams.get("companyCode");
//			String queryPsCaCode = (String) searchParams.get("psCompanyCode");
//			if ("-1".equals(queryCaCode)) {// 指定
//				if (StringUtils.isBlank(companyCode)||"OTHER".equals(companyCode)) {
//					continue;
//				}
//			} else if ("-2".equals(queryCaCode)) {// 未指定
//				if (!StringUtils.isBlank(companyCode)&&!"OTHER".equals(companyCode)) {
//					continue;
//				}
//				companyCode = queryPsCaCode;
//			} else if ("".equals(queryCaCode)) {//全部
//				
//			}else {
//				companyCode = queryPsCaCode;
//			}
//
//			// 发票
//			String isInvoice = (String) searchParams.get("isInvoice");
//			if ("1".equals(isInvoice)) {// 需要发票
//				if (!eOrder.getIsInvoice()) {
//					continue;
//				}
//			} else if ("2".equals(isInvoice)) {// 不需要发票
//				if (eOrder.getIsInvoice()) {
//					continue;
//				}
//			}
//
//			//1指定快递未超区  2未指定快递 超区件  3未指定快递优势区 
//			if("1".equals(scopeFilter)||"2".equals(scopeFilter)) {
//				//会过滤掉超区件
//				String address = eOrder.getAddres() == null ? "" : eOrder.getAddres();
//				List<OutScope> outScopeList = this.outScopeDao.loadByCompanyCode(companyCode,warehouseCode);
//				String zoneFullName;
//				int idx;
//				boolean flag = true;
//				for (OutScope os : outScopeList) {
//					List<ScopeCustomerConfig> configList = os.getCustomerConfigList();
//					boolean existsCustomerCode = false;
//					for(ScopeCustomerConfig config:configList){
//						if(config.getCustomerCode().equals(eOrder.getCustomerCode())){
//							existsCustomerCode = true;
//							break;
//						}
//					}
//					if(existsCustomerCode){
//						continue;
//					}
//					zoneFullName = os.getZoneFullName();
//					idx = address.indexOf(zoneFullName);
//					if (idx >= 0) { // 超区件
//						allOrderList_outScope.add(eOrder);
//						flag = false;
//						break;
//					}
//				}
//				//wms已配置超区，按wms超区过滤。否则调用deppon接口
//				/*if (flag && DOPConstans.LOGISTIC_PROVIDERID_DEFAULT.equals(companyCode)) {
//					flag = depponService.checkArrive(eOrder);
//					if (!flag) {
//						allOrderList_outScope.add(eOrder);
//					}
//				}*/
//				
//				//wms已配置超区，按wms超区过滤。否则调用TTKDEX接口
//				if (flag && "TTKDEX".equals(companyCode)) {
//					flag = ttkdexService.checkArrive(eOrder);
//					if (!flag) {
//						allOrderList_outScope.add(eOrder);
//					}
//				}
//				if (flag && "YUNDA".equals(companyCode)) {
//					flag = yundaService.checkArrive(eOrder);
//					if (!flag) {
//						allOrderList_outScope.add(eOrder);
//					}
//				}
//				if (flag) { // 非超区件
//					allOrderList_not_outScope.add(eOrder);
//				}
//			}else  {
//				//会过赛选优势区
//				String address = eOrder.getAddres() == null ? "" : eOrder.getAddres();
//				String zoneFullName;
//				int idx;
//				boolean inFlg = false;
//				List<InScope> inScopeList = this.inScopeDao.loadByCompanyCode(companyCode,warehouseCode);
//				for (InScope os : inScopeList) {
//					List<ScopeCustomerConfig> configList = os.getCustomerConfigList();
//					boolean existsCustomerCode = false;
//					for(ScopeCustomerConfig config:configList){
//						if(config.getCustomerCode().equals(eOrder.getCustomerCode())){
//							existsCustomerCode = true;
//							break;
//						}
//					}
//					if(existsCustomerCode){
//						continue;
//					}
//					zoneFullName = os.getZoneFullName();
//					idx = address.indexOf(zoneFullName);
//					if (idx >= 0) { // 优势区
//						inFlg = true;
//						break;
//					}
//				}
//				if(inFlg){
//					allOrderList_not_outScope.add(eOrder);
//				}
//			}
		}

		List<EdiOrder> allOrderList_temp;
//		String outScope = (String) searchParams.get("outScope");
		//1指定快递未超区  2未指定快递 超区件  3未指定快递优势区 
		if ("2".equals(scopeFilter)) { // 超区件
			allOrderList_temp = allOrderList_outScope;
		} else { // 非超区件
			allOrderList_temp = allOrderList_not_outScope;
		}

		StringBuffer errorList = new StringBuffer();
		// 区分订单的单件与多件
		for (EdiOrder e : allOrderList_temp) {
			String orderType = e.getOrderType();

			List<EdiOrderItem> orderItems = this.ediOrderItemDao.findByOrdeno(e.getOrdeno());
			e.setOrderItems(orderItems);

			if (orderItems == null || orderItems.size() == 0) {
				errorList.append(e.getOrdeno()).append(";");
				continue;
			}

			if (StringUtils.isEmpty(orderType)) {

				if (orderItems.size() > 1) { // 多种商品,归为多件类型
					e.setOrderType("multiple");
					multiOrderList.add(e);
				} else if (orderItems.get(0).getQty() > 1) { // 一种商品多件,归为多件类型
					e.setOrderType("multiple");
					multiOrderList.add(e);
				} else { // 其它情况，,归为单件类型
					e.setOrderType("single");
					singleOrderList.add(e);
				}
				this.save(e);
			} else {
				if ("single".equals(orderType)) {
					singleOrderList.add(e);
				} else if ("multiple".equals(orderType)) {
					multiOrderList.add(e);
				}
			}

			if (!"".equals(errorList.toString())) {
				throw new Exception("===订单号:" + errorList.toString() + "商品明细不存在");
			}

		}

		// 策略排序
		List<EdiOrder> _singleOrderList = sortByTactics(tacticsType, "single", singleOrderList);
		List<EdiOrder> _multiOrderList = sortByTactics(tacticsType, "multi", multiOrderList);

		
		
		Map<String, List<EdiOrder>> result = new HashMap<String, List<EdiOrder>>();
		result.put("single", _singleOrderList);
		result.put("multi", _multiOrderList);
		

		return result;
	}

	/**
	 * 查询条件封装
	 * @param searchParams
	 * @return
	 */
	private Specification<EdiOrder> getWhereClause(final Map<String, Object> searchParams) {

		return new Specification<EdiOrder>() {

			@Override
			public Predicate toPredicate(Root<EdiOrder> r, CriteriaQuery<?> q, CriteriaBuilder cb) {
				Predicate pre = cb.conjunction();

				// 目的地网点
				String areaGroupCode = (String) searchParams.get("areaGroupCode");
				if (StringUtils.isNotBlank(areaGroupCode)) {
					pre.getExpressions().add(cb.equal(r.get("areaGroupCode"), areaGroupCode));
				}

				// 作业网点
				String warehouseCode = (String) searchParams.get("warehouseCode");
				if (StringUtils.isNotBlank(warehouseCode)) {
					pre.getExpressions().add(cb.equal(r.get("warehouseCode"), warehouseCode));
				}

				// 快递公司
				String companyCode = (String) searchParams.get("companyCode");
				if (StringUtils.isNotBlank(companyCode) && !("-1".equals(companyCode)) && !("-2".equals(companyCode)) && !("-3".equals(companyCode))) {
					pre.getExpressions().add(cb.equal(r.get("cacode"), companyCode));
				}else if("-2".equals(companyCode)) {
				    //add 当前已指定快递  20160725 bug:439
				    String psCurrentCompanyCode = (String) searchParams.get("psCurrentCompanyCode");
				    if (org.apache.commons.lang3.StringUtils.isBlank(psCurrentCompanyCode) || "noAssign".equals(psCurrentCompanyCode)) {
				        Predicate[] companyCodesArray = new Predicate[3];
				        companyCodesArray[0] = cb.isNull(r.get("cacode"));
				        companyCodesArray[1] = cb.equal(r.get("cacode"), "");
				        companyCodesArray[2] = cb.equal(r.get("cacode"), "OTHER");
				        
				        pre.getExpressions().add(cb.or(companyCodesArray));
				    } else if ("all".equals(psCurrentCompanyCode)) {
				        //add 当前已指定快递 为所有，查询所有符合其它条件的订单  20160725 bug:439
				        //do nothings here
				    } else {
				        //add 当前已指定快递 为具体某快递  20160725 bug:439
				        pre.getExpressions().add(cb.equal(r.get("cacode"), psCurrentCompanyCode));
				    }
				}
				

				// 商家
				String customerCode = (String) searchParams.get("customerCode");
				if (StringUtils.isNotBlank(customerCode)) {
					pre.getExpressions().add(cb.equal(r.get("customerCode"), customerCode));
				}
				
				// 订单类型  （1.multiple 2.single）
				String orderType = (String) searchParams.get("orderType");
				if (StringUtils.isNotBlank(orderType)) {
					pre.getExpressions().add(cb.equal(r.get("orderType"), orderType));
				}
				
				// 订单结构  （1.单品 2.组合）
				String tacticsType = (String) searchParams.get("tacticsType");
				if (StringUtils.isNotBlank(orderType) && "promotion".equals(tacticsType)) {
					pre.getExpressions().add(cb.equal(r.get("skuMatch"), "1"));
				}
				
				if (StringUtils.isNotBlank(orderType) && "comb".equals(tacticsType)) {
					pre.getExpressions().add(cb.equal(r.get("skuMatch"), "2"));
				}
				
				 /*String sku=(String) searchParams.get("sku");
			      if(StringUtils.isNotBlank(sku)){
						SetJoin<EdiOrder,EdiOrderItem> depJoin = r.join(r.getModel().getSet("eois", EdiOrderItem.class) , JoinType.LEFT); 
						pre.getExpressions().add(cb.equal(depJoin.get("sku").as(String.class),sku));
				  }*/

				// 创建时间
				Date fromDate = (Date) searchParams.get("fromDate");
				if (fromDate != null) {
					pre.getExpressions().add(cb.greaterThanOrEqualTo(r.<Date> get("crtime"), fromDate));
				}

				Date toDate = (Date) searchParams.get("toDate");
				if (toDate != null) {
					pre.getExpressions().add(cb.lessThanOrEqualTo(r.<Date> get("crtime"), toDate));
				}

				// 订单状态
				String orderStatus = (String) searchParams.get("orderStatus");
				if (StringUtils.isNotBlank(orderStatus)) {
					pre.getExpressions().add(cb.equal(r.get("orderStatus"), orderStatus));
				}
				// 平台
				String erpType = (String) searchParams.get("erpType");
				if (StringUtils.isNotBlank(erpType)) {
					pre.getExpressions().add(cb.equal(r.get("erpType"), erpType));
				}

				// 店铺
				String shopCode = (String) searchParams.get("shopCode");
				if (StringUtils.isNotBlank(shopCode) && (!"-1".equals(shopCode))) {
					pre.getExpressions().add(cb.equal(r.get("shopCode"), shopCode));
				}

				// 目的地
				String addres = (String) searchParams.get("addres");
				if (StringUtils.isNotBlank(addres)) {
					pre.getExpressions().add(cb.like(r.<String> get("addres"), "%" + addres + "%"));
				}

				// 作业状态
				String status = (String) searchParams.get("status");
				if (StringUtils.isNotBlank(status)) {
					pre.getExpressions().add(cb.equal(r.get("status"), status));
				}
				String dispatchFlag = (String) searchParams.get("dispatchFlag");
				if (StringUtils.isNotBlank(dispatchFlag)) {
					pre.getExpressions().add(cb.equal(r.get("dispatchFlag"), dispatchFlag));
				}

				// 订单号
				String orderno = (String) searchParams.get("orderno");
				if (StringUtils.isNotBlank(orderno)) {
					pre.getExpressions().add(cb.or(cb.equal(r.get("ordeno"), orderno.trim()), cb.equal(r.get("fromno"), orderno.trim()), cb.equal(r.get("customerOrdeno"), orderno.trim())));
				}
				
				String isLockOutScopeOrderno = (String) searchParams.get("lockOutScopeOrderno");
				if ("on".equals(isLockOutScopeOrderno)) {
					String lockOutScopeOrdernoStr=(String)searchParams.get("lockOutScopeOrdernoStr");
					if(lockOutScopeOrdernoStr!=null){
						String [] orderNos = lockOutScopeOrdernoStr.split(",");
						
						ComparisonPredicate[] orderNosArray = new ComparisonPredicate[orderNos.length];
						int j = 0;
						for (String orderNo : orderNos) {
							orderNosArray[j] = (ComparisonPredicate) cb.equal(r.get("ordeno"), orderNo);
							j++;
						}
						pre.getExpressions().add(cb.or(orderNosArray));
					}
				}

				
				
				// 商家组
				String customerCodes = (String) searchParams.get("customerCodes");
				if (StringUtils.isNotBlank(customerCodes)) {
					String[] customerCodeSplit = customerCodes.split(":");
					ComparisonPredicate[] tempCustomerCode = new ComparisonPredicate[customerCodeSplit.length];
					int i = 0;
					for (String _customerCode : customerCodeSplit) {
						tempCustomerCode[i] = (ComparisonPredicate) cb.equal(r.get("customerCode"), _customerCode);
						i++;
					}
					pre.getExpressions().add(cb.or(tempCustomerCode));
				}

				// 仓库组
				String areagroups = (String) searchParams.get("areagroups");
				if (StringUtils.isNotBlank(areagroups)) {
					String[] areagroupSplit = areagroups.split(":");
					ComparisonPredicate[] areagroupArray = new ComparisonPredicate[areagroupSplit.length];
					int j = 0;
					for (String _areagroup : areagroupSplit) {
						areagroupArray[j] = (ComparisonPredicate) cb.equal(r.get("warehouseCode"), _areagroup);
						j++;
					}
					pre.getExpressions().add(cb.or(areagroupArray));
				}
				
				// 添加能容订单号、客户订单号、来源单号模糊查询
                String documentno = (String) searchParams.get("documentno");
                if (StringUtils.isNotBlank(documentno)) {
                    try{
                        pre.getExpressions().add(cb.or(cb.like(r.<String> get("ordeno"), "%" + documentno.trim() + "%"), 
                            cb.like(r.<String> get("fromno"), "%" + documentno.trim() + "%"), 
                            cb.like(r.<String> get("customerOrdeno"), "%" + documentno.trim() + "%")));
                    }catch(Exception e){
                        e.printStackTrace();
                    }
                }
                
                //优先派送标志
                String psFlag = (String) searchParams.get("psFlag");
                if (StringUtils.isNotBlank(psFlag)) {
                	if("-1".equals(psFlag)){
                		Predicate[] psFlagArray = new Predicate[2];
                		psFlagArray[0] = cb.equal(r.get("prioritySendFlag"), "0");
                		psFlagArray[1] = cb.equal(r.get("prioritySendFlag"), "1");
				        pre.getExpressions().add(cb.or(psFlagArray));
                	}else{
    					pre.getExpressions().add(cb.equal(r.get("prioritySendFlag"), psFlag));
                	}
				}
                
                //是否有备注
                String remark = (String) searchParams.get("remark");
                if (StringUtils.isNotBlank(remark)) {
                	if("0".equals(remark)){
                		Predicate[] remarkArray = new Predicate[4];
                		remarkArray[0] = cb.isNull(r.get("bumemo"));
                		remarkArray[1] = cb.equal(r.get("bumemo"), "null");
                		remarkArray[2] = cb.equal(r.get("bumemo"), "NULL");
                		remarkArray[3] = cb.equal(r.get("bumemo"),"");
                		 pre.getExpressions().add(cb.or(remarkArray));
                	}else if ("1".equals(remark)){
                		Predicate[] remarkArray = new Predicate[4];
                		remarkArray[0] = cb.isNotNull(r.get("bumemo"));
                		remarkArray[1] = cb.notEqual(r.get("bumemo"), "null");
                		remarkArray[2] = cb.notEqual(r.get("bumemo"), "NULL");
                		remarkArray[3] = cb.notEqual(r.get("bumemo"),"");
                		 pre.getExpressions().add(cb.or(remarkArray));
                	}
				}
                
                String jdEmpty = (String) searchParams.get("jdEmpty");
                if(StringUtils.isNotBlank(jdEmpty)  && jdEmpty.equals("1")){
                    Predicate[] mailNoArray = new Predicate[2];
                    mailNoArray[0] = cb.isNull(r.get("mailNo"));
                    mailNoArray[1] = cb.equal(r.get("mailNo"),"");
                    pre.getExpressions().add(cb.or(mailNoArray));
                }
                
				pre.getExpressions().add(cb.equal(r.get("gymemo"), "1"));
				return pre;
			}
		};
	}

	/**
	 * 生成批次策略排序
	 * @param tacticsType 策略类型　timefirst: 时间优先策略   skufirst:sku集中策略    fix:组合策略   onesku:单品合拣  prepkg:预包装
	 * @param orderType 订单类型   single:单件  multi 多件
	 * @param orderList 源数据
	 * @return 按照策略排序结果
	 */
	private List<EdiOrder> sortByTactics(String tacticsType, String orderType, List<EdiOrder> orderList) {

		List<EdiOrder> result = new ArrayList<EdiOrder>();

		// 时间优先策略
		if (tacticsType.equals("timefirst")) {

			Collections.sort(orderList, new Comparator<EdiOrder>() {
				public int compare(EdiOrder o1, EdiOrder o2) {
					int flag = o1.getCrtime().compareTo(o2.getCrtime());
					return flag;
				}
			});

			return orderList;
		}

		// sku集中策略, 单品合拣, 预包装
		else if (tacticsType.equals("skufirst") || tacticsType.equals("onesku") || tacticsType.equals("prepkg")|| tacticsType.equals("wholePile")) {

			if (orderType.equals("single")) {// 单件

				Map<String, Integer> skuMap = new HashMap<String, Integer>();
				for (EdiOrder o : orderList) {
					String sku = o.getOrderItems().get(0).getSku();
					if (skuMap.containsKey(sku)) {
						skuMap.put(sku, skuMap.get(sku) + 1);
					} else {
						skuMap.put(sku, 1);
					}
				}

				List<Map.Entry<String, Integer>> mappingList = new ArrayList<Map.Entry<String, Integer>>(skuMap.entrySet());
				Collections.sort(mappingList, new Comparator<Map.Entry<String, Integer>>() {
					public int compare(Map.Entry<String, Integer> mapping1, Map.Entry<String, Integer> mapping2) {
						return -mapping1.getValue().compareTo(mapping2.getValue());
					}
				});

				for (Map.Entry<String, Integer> mapping : mappingList) {
					String sku = mapping.getKey();
					for (EdiOrder order : orderList) {
						if (order.getOrderItems().get(0).getSku().equals(sku)) {
							order.setSku(sku);
							result.add(order);
						}
					}
				}
				return result;
			}

			else if (orderType.equals("multi")) {// 多件
				String customerCode = orderList == null || orderList.isEmpty() ? null : orderList.get(0).getCustomerCode();
				if (WmsContants.CUSTOMER_MID.equals(customerCode)) {
					//美的按主品排序
					Collections.sort(orderList, new Comparator<EdiOrder>() {
						@Override
						public int compare(EdiOrder o1, EdiOrder o2) {
							List<EdiOrderItem> orderItems1 = o1.getOrderItems();
							List<EdiOrderItem> orderItems2 = o2.getOrderItems();
							EdiOrderItem item1 = findItem(orderItems1);
							EdiOrderItem item2 = findItem(orderItems2);
							return item1.getSku().compareToIgnoreCase(item2.getSku());
						}
					});
					return orderList;
				}else{
					Map<String, Integer> skuMap = new HashMap<String, Integer>();
					for (EdiOrder o : orderList) {
						for (EdiOrderItem orderItem : o.getOrderItems()) {
							String sku = orderItem.getSku();
							if (skuMap.containsKey(sku)) {
								skuMap.put(sku, skuMap.get(sku) + 1);
							} else {
								skuMap.put(sku, 1);
							}
						}
					}
	
					List<Map.Entry<String, Integer>> mappingList = new ArrayList<Map.Entry<String, Integer>>(skuMap.entrySet());
					Collections.sort(mappingList, new Comparator<Map.Entry<String, Integer>>() {
						public int compare(Map.Entry<String, Integer> mapping1, Map.Entry<String, Integer> mapping2) {
							return -mapping1.getValue().compareTo(mapping2.getValue());
						}
					});
	
					Vector<String> ordernoVector = new Vector<String>();
					for (Map.Entry<String, Integer> mapping : mappingList) {
						String sku = mapping.getKey();
						for (EdiOrder order : orderList) {
							String orderno = order.getOrdeno();
							for (EdiOrderItem orderItem : order.getOrderItems()) {
								if (orderItem.getSku().equals(sku) && !ordernoVector.contains(orderno)) {
									result.add(order);
									ordernoVector.add(orderno);
								}
							}
	
						}
					}
					return result;
				}
			}

		}

		// 大促策略
		else if(tacticsType.equals("promotion")){
			Map<String, Integer> skuMap = new HashMap<String, Integer>();
			for (EdiOrder o : orderList) {
				String sku = o.getOrderItems().get(0).getSku();
				String skuMatch= sku+"_"+o.getSkuQty();
				if (skuMap.containsKey(skuMatch)) {
					skuMap.put(skuMatch, skuMap.get(skuMatch) + 1);
				} else {
					skuMap.put(skuMatch, 1);
				}
			}

			List<Map.Entry<String, Integer>> mappingList = new ArrayList<Map.Entry<String, Integer>>(skuMap.entrySet());
			Collections.sort(mappingList, new Comparator<Map.Entry<String, Integer>>() {
				public int compare(Map.Entry<String, Integer> mapping1, Map.Entry<String, Integer> mapping2) {
					return -mapping1.getValue().compareTo(mapping2.getValue());
				}
			});

			for (Map.Entry<String, Integer> mapping : mappingList) {
				String skuMatch = mapping.getKey();
				String[] sku=skuMatch.split("_");
				for (EdiOrder order : orderList) {
					if (order.getOrderItems().get(0).getSku().equals(sku[0]) && sku[1].equals(order.getSkuQty()+"")) {
						order.setSku(skuMatch);
						result.add(order);
					}
				}
			}
			return result;
		}
		// 组合
		else if(tacticsType.equals("comb")){
			Map<String, Integer> skuMap = new HashMap<String, Integer>();
			for (EdiOrder o : orderList) {
				if(o.getSkuQty()>15)
				{
					continue;
				}
				List<EdiOrderItem> eois = o.getOrderItems();
				StringBuffer sb = new StringBuffer();
				for(EdiOrderItem eoi : eois)
				{
					sb.append(eoi.getSku()).append(eoi.getQty());
				}
				String sku = o.getOrderItems().get(0).getSku();
				String skuMatch= sb.toString();
				if (skuMap.containsKey(skuMatch)) {
					skuMap.put(skuMatch, skuMap.get(skuMatch) + 1);
				} else {
					skuMap.put(skuMatch, 1);
				}
			}

			List<Map.Entry<String, Integer>> mappingList = new ArrayList<Map.Entry<String, Integer>>(skuMap.entrySet());
			Collections.sort(mappingList, new Comparator<Map.Entry<String, Integer>>() {
				public int compare(Map.Entry<String, Integer> mapping1, Map.Entry<String, Integer> mapping2) {
					return -mapping1.getValue().compareTo(mapping2.getValue());
				}
			});

			for (Map.Entry<String, Integer> mapping : mappingList) {
				String skuMatch = mapping.getKey();
				Integer qty = mapping.getValue();
				if(qty < 5)
				{
					continue;
				}
				for (EdiOrder order : orderList) {
					List<EdiOrderItem> eois = order.getOrderItems();
					StringBuffer sb = new StringBuffer();
					for(EdiOrderItem eoi : eois)
					{
						sb.append(eoi.getSku()).append(eoi.getQty());
					}
					String _skuMatch=sb.toString();
					if (_skuMatch.equals(skuMatch)) {
						order.setSku(_skuMatch);
						result.add(order);
					}
				}
			}
			return result;
		}

		return orderList;

	}
	private EdiOrderItem findItem(List<EdiOrderItem> orderItems){
		EdiOrderItem other = null;
		for (EdiOrderItem item : orderItems) {
			if ("1".equals(item.getSellFlg())) {
				other = item;
				break;
			}
			if (other == null || other.getPri() == null) {
				other = item;
			} else if (item.getPri() != null && other.getPri().compareTo(item.getPri()) < 0) {
				other = item;
			}
		}
		return other;
	}
	/**
	 * 
	 * @param orderno
	 * @return
	 */
	public EdiOrder findByOrdernoOrCustomerorderno(String orderno) {
		List<EdiOrder> list = this.ediOrderDao.findByOrdernoOrCustomerorderno(orderno);
		return list.isEmpty() ? null : list.get(0);
	}

	public List<EdiOrder> findByCustomerOrdeno(String ordeno) {
		return this.ediOrderDao.findByCustomerOrdeno(ordeno);
	}

	public EdiOrder findByOrderNoDetail(String orderno) {
		EdiOrder ordeno = ediOrderDao.findByOrdeno(orderno);
		if (ordeno != null) {
			ordeno.setOrderItems(ediOrderItemDao.findByOrdeno(orderno));
		}
		return ordeno;
	}
	
	public EdiOrder findByOrder(String orderno) {
		EdiOrder ordeno = ediOrderDao.findByOrdeno(orderno);
		return ordeno;
	}

	/**
	 * 分页查询订单
	 * @param param
	 * @param i
	 * @param pageSize
	 * @return
	 */
	public Page<EdiOrder> loadPageOrder(Map<String, Object> param, int pageNumber, int pageSize) {
		PageRequest pageRequest = new PageRequest(pageNumber - 1, pageSize);
		Specification<EdiOrder> spec = getWhereClause(param);
		Page<EdiOrder> page = this.ediOrderDao.findAll(spec, pageRequest);
		return page;
	}

	@Transactional(rollbackFor = Exception.class, readOnly = false)
	public void updateEdiOrderDispatchFlag(String ordeno, String warehouseCode) {
		ediOrderDao.updateEdiOrderDispatchFlag(ordeno, warehouseCode);
	}
	
	public void updateEdiOrderDispatchFlagByOrdeno(String ordeno) {
		ediOrderDao.updateEdiOrderDispatchFlagByOrdeno(ordeno);
	}

	public List<EdiOrder> findByCustomerCodeAndCustomerOrdenoAndOrderStatus(
			String customerCode, String customerOrdeno) {
		// TODO Auto-generated method stub
		return ediOrderDao.findByCustomerCodeAndCustomerOrdenoAndOrderStatus(customerCode,customerOrdeno);
	}
	/**
	 * 按照客户编码和仓库查找不可处理的订单
	 */
	public List<EdiOrder> findByCustomerCodeAndWarehouseCode(String customerCode, String warehouseCode, Date fromDate, Date toDate){
		return ediOrderDao.findByCustomerCodeAndWarehouseCode(customerCode, warehouseCode, fromDate, toDate) ;
	}
	

	/**
	 * 添加快递单号
	 *
	 * @param 
	 * @return 
	 * @throws 
	 * @author Songlinhai
	 * @version 1.0.0
	 */
    public String addExpressNo(String[] s){
	    
	    String sql;
	    String msg = "";
	    int count = 0;
	    
        for(int i = 0; i < s.length; i++){
            try{
                
                WorkOrder workOrder = this.workOrderDao.loadWorkOrderByExpressNo(s[i], s[i] + "_");
                if(workOrder != null){
                    msg = msg + "单号" + s[i] + "已被使用;\n";
                    continue;
                }
                
                EdiOrder ediOrder = this.ediOrderDao.findByMailNo(s[i]);
                if(ediOrder != null){
                    msg = msg + "单号" + s[i] + "已被使用;\n";
                    continue;
                }
                
                if(s[i] != null && !s[i].equals("")){
                    sql = "UPDATE edi_order set mail_no = " + "'" + s[i] + "' "
                           + "where customer_code = 'YNBY' and cacode = 'JD' and (mail_no is null or mail_no = '')"
                           + " order by crtime limit 1";
                    count = jdbcTemplate.update(sql); 
                         
                    if(count == 0){
                        msg = msg + "单号" + s[i] + "添加失败;\n";
                    }
                }  
            }catch(Exception e){
                log.error("添加快递单号失败" + e);
                msg = msg +  "单号" + s[i] + "添加失败;\n";
            }
        }
        
        return msg;
    }
    
    /**
     * 添加快递单号
     *
     * @param 
     * @return 
     * @throws 
     * @author Songlinhai
     * @version 1.0.0
     */
    public String addExpressNoNew(Map<String, String> map){
        
        String sql;
        String msg = "";
        int count = 0;
        
        for(String key : map.keySet()){
            try{   
                WorkOrder workOrder = this.workOrderDao.loadWorkOrderByExpressNo(key, key + "_");
                if(workOrder != null){
                    msg = msg + "单号" + key + "已被使用;\n";
                    continue;
                }
                
                EdiOrder ediOrder = this.ediOrderDao.findByMailNo(map.get(key));
                if(ediOrder != null){
                    msg = msg + "单号" + key + "已被使用;\n";
                    continue;
                }
                
                if(key != null && !key.equals("")){
                    sql = "update edi_order set mail_no = '" + map.get(key) + "' "
                           + "where cacode = 'JD' and (mail_no is null or mail_no = '') "
                           + "and ordeno = '" + key + "'";
                    count = jdbcTemplate.update(sql);
                    if(count == 0){
                        msg = msg + "单号" + key + "添加失败;\n";
                    }
                }
            }catch(Exception e){
                log.error("添加快递单号失败" + e);
                msg = msg +  "单号" + key + "添加失败;\n";
            }
        }
        return msg;
    }
    
    /**
	 *导出含备注订单
	 * 
	 *
	 * @param customerCodes
	 * @param warehouseCode
	 * @param fromDate
	 * @param toDate
	 * @return [参数说明]
	 * @author <a href=mailto:zhangweize@nryuncang.com>zhangweize</a>
	 * @version 1.0.0
	 */
	 public List<Object[]> exceptRemarkOrdernos(String customerCodes, String warehouseCode, String fromDate, String toDate) {
	        return ediOrderDao.exceptRemarkOrdernos(customerCodes, warehouseCode, fromDate, toDate);
	    }
}
